raise vwdw stacking tweak, drag handle for transitions, cleanup histogram plugin... master
authorGood Guy <good1.2guy@gmail.com>
Sun, 27 Sep 2020 20:07:22 +0000 (14:07 -0600)
committerGood Guy <good1.2guy@gmail.com>
Sun, 27 Sep 2020 20:07:22 +0000 (14:07 -0600)
257 files changed:
cinelerra-5.1/blds/PKGBUILD
cinelerra-5.1/blds/cinelerra.spec
cinelerra-5.1/blds/debian/changelog
cinelerra-5.1/blds/debian/control
cinelerra-5.1/cinelerra/apatchgui.C
cinelerra-5.1/cinelerra/apatchgui.h
cinelerra-5.1/cinelerra/apatchgui.inc
cinelerra-5.1/cinelerra/appearanceprefs.C
cinelerra-5.1/cinelerra/appearanceprefs.h
cinelerra-5.1/cinelerra/asset.C
cinelerra-5.1/cinelerra/auto.C
cinelerra-5.1/cinelerra/auto.h
cinelerra-5.1/cinelerra/automation.inc
cinelerra-5.1/cinelerra/autos.C
cinelerra-5.1/cinelerra/autos.h
cinelerra-5.1/cinelerra/awindowgui.C
cinelerra-5.1/cinelerra/brender.C
cinelerra-5.1/cinelerra/cache.C
cinelerra-5.1/cinelerra/colorpicker.C
cinelerra-5.1/cinelerra/cwindow.C
cinelerra-5.1/cinelerra/cwindowgui.C
cinelerra-5.1/cinelerra/cwindowtool.C
cinelerra-5.1/cinelerra/cwindowtool.h
cinelerra-5.1/cinelerra/cwindowtool.inc
cinelerra-5.1/cinelerra/editpanel.C
cinelerra-5.1/cinelerra/editpopup.C
cinelerra-5.1/cinelerra/editpopup.h
cinelerra-5.1/cinelerra/edits.C
cinelerra-5.1/cinelerra/edits.h
cinelerra-5.1/cinelerra/edl.inc
cinelerra-5.1/cinelerra/edlsession.C
cinelerra-5.1/cinelerra/edlsession.h
cinelerra-5.1/cinelerra/ffmpeg.C
cinelerra-5.1/cinelerra/ffmpeg.h
cinelerra-5.1/cinelerra/file.C
cinelerra-5.1/cinelerra/file.h
cinelerra-5.1/cinelerra/filebase.C
cinelerra-5.1/cinelerra/fileref.C
cinelerra-5.1/cinelerra/fileref.h
cinelerra-5.1/cinelerra/filethread.C
cinelerra-5.1/cinelerra/floatauto.C
cinelerra-5.1/cinelerra/floatauto.h
cinelerra-5.1/cinelerra/floatautos.C
cinelerra-5.1/cinelerra/floatautos.h
cinelerra-5.1/cinelerra/fourier.C
cinelerra-5.1/cinelerra/framecache.C
cinelerra-5.1/cinelerra/framecache.h
cinelerra-5.1/cinelerra/gwindowgui.C
cinelerra-5.1/cinelerra/keyframepopup.C
cinelerra-5.1/cinelerra/keyframepopup.h
cinelerra-5.1/cinelerra/keyframepopup.inc
cinelerra-5.1/cinelerra/labels.C
cinelerra-5.1/cinelerra/labels.h
cinelerra-5.1/cinelerra/mainmenu.C
cinelerra-5.1/cinelerra/mainmenu.h
cinelerra-5.1/cinelerra/mainmenu.inc
cinelerra-5.1/cinelerra/mainsession.C
cinelerra-5.1/cinelerra/mainsession.h
cinelerra-5.1/cinelerra/mainsession.inc
cinelerra-5.1/cinelerra/mainundo.C
cinelerra-5.1/cinelerra/mwindow.C
cinelerra-5.1/cinelerra/mwindow.h
cinelerra-5.1/cinelerra/mwindowedit.C
cinelerra-5.1/cinelerra/mwindowgui.C
cinelerra-5.1/cinelerra/mwindowgui.h
cinelerra-5.1/cinelerra/new.C
cinelerra-5.1/cinelerra/packagedispatcher.C
cinelerra-5.1/cinelerra/packagerenderer.C
cinelerra-5.1/cinelerra/packagerenderer.h
cinelerra-5.1/cinelerra/packagerenderer.inc
cinelerra-5.1/cinelerra/patchbay.C
cinelerra-5.1/cinelerra/patchbay.h
cinelerra-5.1/cinelerra/patchgui.C
cinelerra-5.1/cinelerra/patchgui.h
cinelerra-5.1/cinelerra/patchgui.inc
cinelerra-5.1/cinelerra/performanceprefs.C
cinelerra-5.1/cinelerra/performanceprefs.h
cinelerra-5.1/cinelerra/performanceprefs.inc
cinelerra-5.1/cinelerra/playbackengine.C
cinelerra-5.1/cinelerra/playbackengine.h
cinelerra-5.1/cinelerra/pluginclient.C
cinelerra-5.1/cinelerra/pluginfclient.C
cinelerra-5.1/cinelerra/preferences.C
cinelerra-5.1/cinelerra/preferences.h
cinelerra-5.1/cinelerra/preferencesthread.C
cinelerra-5.1/cinelerra/preferencesthread.h
cinelerra-5.1/cinelerra/renderfarm.h
cinelerra-5.1/cinelerra/renderfarmclient.C
cinelerra-5.1/cinelerra/savefile.C
cinelerra-5.1/cinelerra/savefile.h
cinelerra-5.1/cinelerra/track.C
cinelerra-5.1/cinelerra/track.h
cinelerra-5.1/cinelerra/trackcanvas.C
cinelerra-5.1/cinelerra/trackcanvas.h
cinelerra-5.1/cinelerra/tracks.C
cinelerra-5.1/cinelerra/tracks.h
cinelerra-5.1/cinelerra/tracksedit.C
cinelerra-5.1/cinelerra/transitionpopup.C
cinelerra-5.1/cinelerra/transitionpopup.h
cinelerra-5.1/cinelerra/videodevice.C
cinelerra-5.1/cinelerra/virtualvconsole.C
cinelerra-5.1/cinelerra/vmodule.C
cinelerra-5.1/cinelerra/vpatchgui.C
cinelerra-5.1/cinelerra/vpatchgui.h
cinelerra-5.1/cinelerra/vpatchgui.inc
cinelerra-5.1/cinelerra/vrender.C
cinelerra-5.1/configure.ac
cinelerra-5.1/doc/shortcuts.html
cinelerra-5.1/ffmpeg/audio/mpeg1_mp2.mpeg [new file with mode: 0644]
cinelerra-5.1/ffmpeg/plugin.opts
cinelerra-5.1/ffmpeg/video/AVC_Intra_100.mp4 [new file with mode: 0644]
cinelerra-5.1/ffmpeg/video/div3.qt
cinelerra-5.1/ffmpeg/video/div3v2.qt
cinelerra-5.1/ffmpeg/video/div5.qt
cinelerra-5.1/ffmpeg/video/ffv1.avi [new file with mode: 0644]
cinelerra-5.1/ffmpeg/video/flv_h264.flv [new file with mode: 0644]
cinelerra-5.1/ffmpeg/video/huffyuv_screencapture.mov
cinelerra-5.1/ffmpeg/video/mjpeg_444.qt
cinelerra-5.1/ffmpeg/video/mpeg1.mpeg [new file with mode: 0644]
cinelerra-5.1/ffmpeg/video/mpeg2.mpeg [new file with mode: 0644]
cinelerra-5.1/ffmpeg/video/msmpeg4.avi
cinelerra-5.1/ffmpeg/video/xvid.avi
cinelerra-5.1/guicast/bcdisplayinfo.C
cinelerra-5.1/guicast/bcdisplayinfo.h
cinelerra-5.1/guicast/vframe.C
cinelerra-5.1/info/plugins.txt
cinelerra-5.1/msg/txt
cinelerra-5.1/plugins/Makefile
cinelerra-5.1/plugins/compressormulti/comprmultigui.C
cinelerra-5.1/plugins/histogram/debug [deleted file]
cinelerra-5.1/plugins/histogram/histogram.C
cinelerra-5.1/plugins/histogram/histogram.h
cinelerra-5.1/plugins/histogram/histogram.inc
cinelerra-5.1/plugins/histogram/histogramconfig.C
cinelerra-5.1/plugins/histogram/histogramconfig.h
cinelerra-5.1/plugins/histogram/histogramwindow.C
cinelerra-5.1/plugins/histogram/histogramwindow.h
cinelerra-5.1/plugins/histogram/histogramwindow.inc
cinelerra-5.1/plugins/motion/motion.C
cinelerra-5.1/plugins/motion/motion.h
cinelerra-5.1/plugins/motion/motionscan.C
cinelerra-5.1/plugins/motion/motionscan.h
cinelerra-5.1/plugins/motion/motionwindow.C
cinelerra-5.1/plugins/motion/motionwindow.h
cinelerra-5.1/plugins/motion/opencvwrapper.C [deleted file]
cinelerra-5.1/plugins/motion/opencvwrapper.h [deleted file]
cinelerra-5.1/plugins/motion/opencvwrapper.inc [deleted file]
cinelerra-5.1/plugins/scale/scale.C
cinelerra-5.1/plugins/scale/scale.h
cinelerra-5.1/plugins/scale/scalewin.C
cinelerra-5.1/plugins/theme_blond/blondtheme.C
cinelerra-5.1/plugins/theme_blond/data/edge_off.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond/data/edge_on.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond/data/span_off.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond/data/span_on.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond/data/tan_bump.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond/data/tan_free.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond/data/tan_tangent.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond_cv/blondcvtheme.C
cinelerra-5.1/plugins/theme_blond_cv/data/edge_off.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond_cv/data/edge_on.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond_cv/data/span_off.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond_cv/data/span_on.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond_cv/data/tan_bump.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond_cv/data/tan_free.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blond_cv/data/tan_tangent.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue/bluetheme.C
cinelerra-5.1/plugins/theme_blue/data/edge_off.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue/data/edge_on.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue/data/span_off.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue/data/span_on.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue/data/tan_bump.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue/data/tan_free.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue/data/tan_tangent.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue_dot/bluedottheme.C
cinelerra-5.1/plugins/theme_blue_dot/data/edge_off.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue_dot/data/edge_on.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue_dot/data/span_off.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue_dot/data/span_on.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue_dot/data/tan_bump.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue_dot/data/tan_free.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_blue_dot/data/tan_tangent.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_bright/brighttheme.C
cinelerra-5.1/plugins/theme_bright/data/edge_off.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_bright/data/edge_on.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_bright/data/span_off.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_bright/data/span_on.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_bright/data/tan_bump.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_bright/data/tan_free.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_bright/data/tan_tangent.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_cakewalk/cakewalk.C
cinelerra-5.1/plugins/theme_cakewalk/data/edge_off.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_cakewalk/data/edge_on.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_cakewalk/data/span_off.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_cakewalk/data/span_on.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_cakewalk/data/tan_bump.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_cakewalk/data/tan_free.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_cakewalk/data/tan_tangent.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_hulk/data/edge_off.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_hulk/data/edge_on.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_hulk/data/span_off.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_hulk/data/span_on.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_hulk/data/tan_bump.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_hulk/data/tan_free.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_hulk/data/tan_tangent.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_hulk/hulktheme.C
cinelerra-5.1/plugins/theme_neophyte/data/edge_off.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_neophyte/data/edge_on.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_neophyte/data/span_off.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_neophyte/data/span_on.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_neophyte/data/tan_bump.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_neophyte/data/tan_free.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_neophyte/data/tan_tangent.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_neophyte/neophyte.C
cinelerra-5.1/plugins/theme_pinklady/data/edge_off.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_pinklady/data/edge_on.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_pinklady/data/span_off.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_pinklady/data/span_on.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_pinklady/data/tan_bump.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_pinklady/data/tan_free.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_pinklady/data/tan_tangent.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_pinklady/pinkladytheme.C
cinelerra-5.1/plugins/theme_suv/data/edge_off.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_suv/data/edge_on.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_suv/data/expandpatch_checked.png
cinelerra-5.1/plugins/theme_suv/data/expandpatch_checkedhi.png
cinelerra-5.1/plugins/theme_suv/data/expandpatch_dn.png
cinelerra-5.1/plugins/theme_suv/data/expandpatch_hi.png
cinelerra-5.1/plugins/theme_suv/data/expandpatch_up.png
cinelerra-5.1/plugins/theme_suv/data/new_bg.png
cinelerra-5.1/plugins/theme_suv/data/new_bigbutton_dn.png
cinelerra-5.1/plugins/theme_suv/data/new_bigbutton_hi.png
cinelerra-5.1/plugins/theme_suv/data/new_bigbutton_up.png
cinelerra-5.1/plugins/theme_suv/data/span_off.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_suv/data/span_on.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_suv/data/tan_bump.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_suv/data/tan_free.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_suv/data/tan_tangent.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_suv/data/tumblepatch_bottom.png
cinelerra-5.1/plugins/theme_suv/data/tumblepatch_hi.png
cinelerra-5.1/plugins/theme_suv/data/tumblepatch_top.png
cinelerra-5.1/plugins/theme_suv/data/tumblepatch_up.png
cinelerra-5.1/plugins/theme_suv/suv.C
cinelerra-5.1/plugins/theme_unflat/data/edge_off.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_unflat/data/edge_on.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_unflat/data/span_off.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_unflat/data/span_on.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_unflat/data/tan_bump.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_unflat/data/tan_free.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_unflat/data/tan_tangent.png [new file with mode: 0644]
cinelerra-5.1/plugins/theme_unflat/unflattheme.C
cinelerra-5.1/plugins/titler/titler.C
cinelerra-5.1/po/es.po
cinelerra-5.1/po/ru.po
cinelerra-5.1/thirdparty/src/dav1d-0.5.1.patch1 [moved from cinelerra-5.1/thirdparty/src/dav1d-0.7.1.patch1 with 92% similarity]
cinelerra-5.1/thirdparty/src/dav1d-0.5.1.tar.gz [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/dav1d-0.7.1.tar.xz [deleted file]

index d53d39237d9c689d735bf697a26a79f9c2430bd7..bc8a72852c0c95a91d4aa764d47d1d2ee03a86bb 100644 (file)
@@ -1,7 +1,7 @@
 # Maintainer: goodguy <lists.cinelerra-gg.org>
 pkgname=cin
 pkgver=5.1
-pkgrel=20200731
+pkgrel=20200831
 pkgdesc="Cinelerra git://git.cinelerra-gg.org/goodguy/cinelerra.git ($pkgrel)"
 arch=('x86_64')
 url="https://www.cinelerra-gg.org"
index 98df5a419a5bb8bb8b6d211c12a59ea9beb46c74..df7ec9237a6caf90f2cb198f5c03fc8d72241f9a 100644 (file)
@@ -1,4 +1,4 @@
-%define ver 20200731
+%define ver 20200831
 %define cin cinelerra
 Summary: Multimedia Editing and construction
 
index f73636babf86a49f12a775356b20f950023d7ecf..c68f4f136a89b8db98e921dbdab08fbb64c5dc14 100644 (file)
@@ -1,4 +1,4 @@
-cin (1:5.1.20200731) unstable; urgency=low
+cin (1:5.1.20200831) unstable; urgency=low
 
   [ guy goode ]
 
index 629d550f738283602b72d35ecb97dba4c15e7b4f..02145962591c1e86782d757a593a0dff59d88c43 100644 (file)
@@ -1,7 +1,7 @@
 Source: cin
 Section: video
 Priority: optional
-Standards-Version: 5.1.20200731
+Standards-Version: 5.1.20200831
 Maintainer: mailing list <cin@lists.cinelerra-gg.org>
 Homepage: https://www.cinelerra-gg.org/
 Build-Depends:
index 59d18244c34260c9f4d26a1874f86bc22234d112..d44b584b46812092c4cb14cb79c79206b90e336f 100644 (file)
@@ -182,14 +182,12 @@ void APatchGUI::update_faders(float v)
        double position = mwindow->edl->local_session->get_selectionstart(1);
        Autos *fade_autos = atrack->automation->autos[AUTOMATION_FADE];
        int need_undo = !fade_autos->auto_exists_for_editing(position);
-
        mwindow->undo->update_undo_before(_("fade"), need_undo ? 0 : this);
        FloatAuto *current = (FloatAuto*)fade_autos->get_auto_for_editing(position);
-       float change = v - current->get_value();
-       current->set_value(v);
-
+       float change = v - current->get_value(edge);
+       current->bump_value(v, edge, span);
        if( track->is_ganged() && track->is_armed() )
-               patchbay->synchronize_faders(change, TRACK_AUDIO, track);
+               patchbay->synchronize_faders(change, TRACK_AUDIO, track, edge, span);
        mwindow->undo->update_undo_after(_("fade"), LOAD_AUTOMATION);
        change_source = 0;
 
@@ -220,33 +218,64 @@ int AFadePatch::handle_event()
        return 1;
 }
 
-AKeyFadePatch::AKeyFadePatch(MWindow *mwindow, APatchGUI *patch, int x, int y)
- : BC_SubWindow(x,y, xS(200),yS(20), GWindowGUI::auto_colors[AUTOMATION_FADE])
+AKeyFadePatch::AKeyFadePatch(MWindow *mwindow, APatchGUI *gui,
+                       int bump, int x, int y)
+ : BC_SubWindow(x,y, xS(200)+4,yS(bump ? 50 : 24)+4,
+               GWindowGUI::auto_colors[AUTOMATION_FADE])
 {
        this->mwindow = mwindow;
-       this->patch = patch;
+       this->gui = gui;
+}
+AKeyFadePatch::~AKeyFadePatch()
+{
 }
 
 void AKeyFadePatch::create_objects()
 {
-       int x = 0, y = 0;
-       float v = mwindow->get_float_auto(patch, AUTOMATION_FADE)->get_value();
+       int x = 2, x1 = x, y = 0, dy = 0;
+       FloatAuto *fade_auto = mwindow->get_float_auto(gui, AUTOMATION_FADE);
+       float v = fade_auto->get_value(gui->edge);
        add_subwindow(akey_fade_text = new AKeyFadeText(this, x, y, xS(64), v));
        x += akey_fade_text->get_w();
+       dy = bmax(dy, akey_fade_text->get_h());
        VFrame **lok_images = mwindow->theme->get_image_set("lok");
-       int w1 = get_w() - x - lok_images[0]->get_w();
+       int w1 = get_w()-2 - x - lok_images[0]->get_w();
        add_subwindow(akey_fade_slider = new AKeyFadeSlider(this, x, y, w1, v));
        x += akey_fade_slider->get_w();
+       dy = bmax(dy, akey_fade_slider->get_h());
        add_subwindow(akey_fade_ok = new AKeyFadeOK(this, x, y, lok_images));
+       dy = bmax(dy, akey_fade_ok->get_h());
+       if( fade_auto->is_bump() ) {
+               y += dy;
+               set_color(get_resources()->get_bg_color());
+               draw_box(0,y, get_w(),get_h());
+               add_subwindow(auto_edge = new AKeyPatchAutoEdge(mwindow, this, x1, y));
+               x1 += auto_edge->get_w() + xS(15);
+               add_subwindow(auto_span = new AKeyPatchAutoSpan(mwindow, this, x1, y));
+       }
+       draw_3d_border(0,0, get_w(), get_h(), 0);
        activate();
        show_window();
 }
 
+void AKeyFadePatch::set_edge(int edge)
+{
+       gui->edge = edge;
+       FloatAuto *fade_auto = mwindow->get_float_auto(gui, AUTOMATION_FADE);
+       float v = fade_auto->get_value(edge);
+       update(v);
+}
+
+void AKeyFadePatch::set_span(int span)
+{
+       gui->span = span;
+}
+
 void AKeyFadePatch::update(float v)
 {
        akey_fade_text->update(v);
        akey_fade_slider->update(v);
-       patch->update_faders(v);
+       gui->update_faders(v);
 }
 
 AKeyFadeOK::AKeyFadeOK(AKeyFadePatch *akey_fade_patch, int x, int y, VFrame **images)
@@ -257,9 +286,8 @@ AKeyFadeOK::AKeyFadeOK(AKeyFadePatch *akey_fade_patch, int x, int y, VFrame **im
 
 int AKeyFadeOK::handle_event()
 {
-       MWindowGUI *mgui = akey_fade_patch->mwindow->gui;
-       delete mgui->keyvalue_popup;
-       mgui->keyvalue_popup = 0;
+       MWindow *mwindow = akey_fade_patch->mwindow;
+       mwindow->gui->close_keyvalue_popup();
        return 1;
 }
 
@@ -278,7 +306,7 @@ int AKeyFadeText::handle_event()
 }
 
 AKeyFadeSlider::AKeyFadeSlider(AKeyFadePatch *akey_fade_patch, int x, int y, int w, float v)
- : AFadePatch(akey_fade_patch->patch, x, y, w, v)
+ : AFadePatch(akey_fade_patch->gui, x, y, w, v)
 {
        this->akey_fade_patch = akey_fade_patch;
 }
@@ -310,19 +338,13 @@ int APanPatch::handle_event()
        double position = mwindow->edl->local_session->get_selectionstart(1);
        Autos *pan_autos = patch->atrack->automation->autos[AUTOMATION_PAN];
        int need_undo = !pan_autos->auto_exists_for_editing(position);
-
        mwindow->undo->update_undo_before(_("pan"), need_undo ? 0 : this);
-
        current = (PanAuto*)pan_autos->get_auto_for_editing(position);
-
        current->handle_x = get_stick_x();
        current->handle_y = get_stick_y();
        memcpy(current->values, get_values(), sizeof(float) * mwindow->edl->session->audio_channels);
-
        mwindow->undo->update_undo_after(_("pan"), LOAD_AUTOMATION);
-
        mwindow->sync_parameters(CHANGE_PARAMS);
-
        if( need_undo && mwindow->edl->session->auto_conf->autos[AUTOMATION_PAN] ) {
                mwindow->gui->draw_overlays(1);
        }
@@ -374,3 +396,35 @@ AMixPatch::~AMixPatch()
 {
 }
 
+AKeyPatchAutoEdge::AKeyPatchAutoEdge(MWindow *mwindow,
+               AKeyFadePatch *patch, int x, int y)
+ : BC_Toggle(x, y, mwindow->theme->get_image_set("bump_edge"),
+                patch->gui->edge,_("Edge"))
+{
+       this->mwindow = mwindow;
+       this->patch = patch;
+       set_tooltip(_("Bump uses left edge"));
+}
+
+int AKeyPatchAutoEdge::handle_event()
+{
+       patch->set_edge(get_value());
+       return 1;
+}
+
+AKeyPatchAutoSpan::AKeyPatchAutoSpan(MWindow *mwindow,
+               AKeyFadePatch *patch, int x, int y)
+ :  BC_Toggle(x, y, mwindow->theme->get_image_set("bump_span"),
+               patch->gui->span,_("Span"))
+{
+       this->mwindow = mwindow;
+       this->patch = patch;
+       set_tooltip(_("Bump spans to next"));
+}
+
+int AKeyPatchAutoSpan::handle_event()
+{
+       patch->set_span(get_value());
+       return 1;
+}
+
index 5b8411a43762677fc4da49c2f5ec1120a31ba552..a9bee09529dda94267225531f257ee51746f7423 100644 (file)
@@ -59,15 +59,21 @@ public:
 class AKeyFadePatch : public BC_SubWindow
 {
 public:
-       AKeyFadePatch(MWindow *mwindow, APatchGUI *patch, int x, int y);
+       AKeyFadePatch(MWindow *mwindow, APatchGUI *patch,
+                       int bump, int x, int y);
+       ~AKeyFadePatch();
        void create_objects();
+       void set_edge(int edge);
+       void set_span(int span);
        void update(float v);
 
        MWindow *mwindow;
-       APatchGUI *patch;
+       APatchGUI *gui;
        AKeyFadeOK *akey_fade_ok;
        AKeyFadeText *akey_fade_text;
        AKeyFadeSlider *akey_fade_slider;
+       AKeyPatchAutoEdge *auto_edge;
+       AKeyPatchAutoSpan *auto_span;
 };
 
 class AKeyFadeOK : public BC_Button
@@ -131,4 +137,22 @@ public:
        ~AMixPatch();
 };
 
+class AKeyPatchAutoEdge : public BC_Toggle
+{
+public:
+       AKeyPatchAutoEdge(MWindow *mwindow, AKeyFadePatch *patch, int x, int y);
+       int handle_event();
+       MWindow *mwindow;
+       AKeyFadePatch *patch;
+};
+
+class AKeyPatchAutoSpan : public BC_Toggle
+{
+public:
+       AKeyPatchAutoSpan(MWindow *mwindow, AKeyFadePatch *patch, int x, int y);
+       int handle_event();
+       MWindow *mwindow;
+       AKeyFadePatch *patch;
+};
+
 #endif
index 866a167df4f21183228a0b7dccdbb466489d180b..6a62b83efeeb48ed5b63546f12848f3579c5f0c3 100644 (file)
@@ -36,5 +36,7 @@ class APanPatch;
 class AKeyPanPatch;
 class AMeterPatch;
 class AMixPatch;
+class AKeyPatchAutoEdge;
+class AKeyPatchAutoSpan;
 
 #endif
index 435f70ad1bf6df6a54397e854a0f4ca2ee2ef3fd..1f87883551ba69b5096b71932046dd05437ec904 100644 (file)
@@ -95,7 +95,7 @@ void AppearancePrefs::create_objects()
        add_subwindow(plugin_icons = new ViewPluginIcons(x1, y, pwindow));
        plugin_icons->create_objects();
        y += plugin_icons->get_h() + ys10;
-       add_subwindow(new BC_Title(x, y, _("Locale:")));
+       add_subwindow(new BC_Title(x, y, _("Language:")));
        LayoutLocale *layout_locale;
        add_subwindow(layout_locale = new LayoutLocale(x1, y, pwindow));
        layout_locale->create_objects();
@@ -184,9 +184,8 @@ void AppearancePrefs::create_objects()
        y += ys35;
        add_subwindow(title = new BC_Title(x, y, _("Composer BG Color:")));
        int clr_color = pwindow->thread->edl->session->cwindow_clear_color;
-       int clr_alpha = pwindow->thread->edl->session->cwindow_clear_alpha;
         add_subwindow(cwdw_bg_color = new Composer_BG_Color(pwindow,
-               x2, y, xS(80), yS(24), clr_color, clr_alpha));
+               x2, y, xS(80), yS(24), clr_color));
        draw_3d_border(x2-2,y-2, xS(80)+4,xS(24)+4, 1);
        cwdw_bg_color->create_objects();
        x2 += cwdw_bg_color->get_w();
@@ -206,7 +205,7 @@ void AppearancePrefs::create_objects()
        if( y2 < y ) y2 = y;
 
        add_subwindow(new BC_Bar(x0, y2, get_w()-x0 - xs30));
-       y += ys15;
+       y += ys35;
 
        x = x0;  y1 = y;
        add_subwindow(title = new BC_Title(x, y, _("Warnings:"), LARGEFONT,
@@ -932,8 +931,8 @@ int RectifyAudioToggle::handle_event()
 }
 
 Composer_BG_Color::Composer_BG_Color(PreferencesWindow *pwindow,
-               int x, int y, int w, int h, int color, int alpha)
- : ColorBoxButton(_("Composer BG color"), x, y, w, h, color, alpha, 1)
+               int x, int y, int w, int h, int color)
+ : ColorBoxButton(_("Composer BG color"), x, y, w, h, color, -1, 1)
 {
        this->pwindow = pwindow;
 }
@@ -955,7 +954,6 @@ void Composer_BG_Color::handle_done_event(int result)
 int Composer_BG_Color::handle_new_color(int color, int alpha)
 {
        pwindow->thread->edl->session->cwindow_clear_color = color;
-       pwindow->thread->edl->session->cwindow_clear_alpha = alpha;
        return 1;
 }
 
index fed29a98a314fcd2217c3aedf55526f0c58e0af0..c7d95ecbfea6db90745662e54ba15acb8202514f 100644 (file)
@@ -438,7 +438,7 @@ class Composer_BG_Color : public ColorBoxButton
 {
 public:
        Composer_BG_Color(PreferencesWindow *pwindow,
-               int x, int y, int w, int h, int color, int alpha);
+               int x, int y, int w, int h, int color);
        ~Composer_BG_Color();
        void handle_done_event(int result);
        int handle_new_color(int color, int alpha);
index fab58403d7c54cfaefccc06232ffcf45d9f97589..23586a06e4031f9702ee673f5543700940c3ead6 100644 (file)
@@ -181,9 +181,9 @@ void Asset::boundaries()
 // sample_rate & frame_rate are user defined
 //     CLAMP(sample_rate, 1, 1000000);
 //     CLAMP(frame_rate, 0.001, 1000000);
-       CLAMP(channels, 0, 16);
-       CLAMP(width, 0, 10000);
-       CLAMP(height, 0, 10000);
+       CLAMP(channels, 0, MAX_CHANNELS-1);
+       CLAMP(width, 0, ASSET_MAX_WIDTH);
+       CLAMP(height, 0, ASSET_MAX_HEIGHT);
 //printf("Asset::boundaries %d %d %f\n", __LINE__, sample_rate, frame_rate);
 }
 
index 4171fa83d18338a46897ff2877852550279ab9ca..87a2ddafe08d4b58bff46f224b40811892ecf1ed 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "auto.h"
 #include "autos.h"
+#include "edl.h"
 #include "filexml.h"
 
 Auto::Auto()
@@ -29,10 +30,11 @@ Auto::Auto()
        this->edl = 0;
        this->autos = 0;
        position = 0;
-       skip = 0;
        WIDTH = xS(10);
        HEIGHT = yS(10);
        is_default = 0;
+       id = EDL::next_id();
+       orig_id = id;
 }
 
 Auto::Auto(EDL *edl, Autos *autos)
@@ -41,10 +43,11 @@ Auto::Auto(EDL *edl, Autos *autos)
        this->edl = edl;
        this->autos = autos;
        position = 0;
-       skip = 0;
        WIDTH = xS(10);
        HEIGHT = yS(10);
        is_default = 0;
+       id = EDL::next_id();
+       orig_id = id;
 }
 
 Auto& Auto::operator=(Auto& that)
@@ -66,6 +69,7 @@ void Auto::copy(int64_t start, int64_t end, FileXML *file, int default_only)
 
 void Auto::copy_from(Auto *that)
 {
+       this->orig_id = that->orig_id;
        this->position = that->position;
 }
 
@@ -75,8 +79,11 @@ int Auto::interpolate_from(Auto *a1, Auto *a2, int64_t new_position, Auto *templ
        if( !templ ) templ = previous;
        if( !templ && this->autos )
                templ = this->autos->default_auto;
-       if( templ )
+       if( templ ) {
+               int orig_id = this->orig_id;
                copy_from(templ);
+               this->orig_id = orig_id;
+       }
        position = new_position;
        return 0;
 }
index f91451ef03b19d8b54344ccbf6231396b55a090f..6330952459a3c14262598ecfe2cc86d0b328f1e6 100644 (file)
@@ -57,10 +57,9 @@ public:
 
        virtual void get_caption(char *string) {};
 
-
-       int skip;       // if added by selection event for moves
        EDL *edl;
        Autos *autos;
+       int id, orig_id;
        int WIDTH, HEIGHT;
 // Units native to the track
        int is_default;
index 31f58a663016158b04d187f74e74a286e8fadf80..53e498d13e95ffa97b147b0581d17dbd8af0f1f8 100644 (file)
@@ -43,6 +43,7 @@ enum
        AUTOMATION_PAN,
        AUTOMATION_MODE,
        AUTOMATION_MASK,
+// must be last or autos move when pasted due to speed pos shifts
        AUTOMATION_SPEED,
        AUTOMATION_TOTAL
 };
index 73e89a917ceb448f5510379ecea05f6a63e74987..a48afbb508531f1abc99c477dbf9a6a46f853df5 100644 (file)
@@ -265,20 +265,21 @@ int Autos::auto_exists_for_editing(double position)
 
 Auto* Autos::get_auto_at_position(double position)
 {
-       int64_t unit_position = track->to_units(position, 0);
 
-       for(Auto *current = first;
-               current;
-               current = NEXT)
-       {
-               if(edl->equivalent(current->position, unit_position))
-               {
+       for( Auto *current=first; current; current=NEXT ) {
+               double pos = track->from_units(current->position);
+               if( edl->equivalent(position, pos) )
                        return current;
-               }
        }
        return 0;
 }
 
+Auto* Autos::get_auto(int id)
+{
+       Auto *current = first;
+       while( current && current->orig_id != id ) current = NEXT;
+       return current;
+}
 
 Auto* Autos::get_auto_for_editing(double position, int create)
 {
@@ -290,7 +291,7 @@ Auto* Autos::get_auto_for_editing(double position, int create)
        get_prev_auto(track->to_units(position, 0), PLAY_FORWARD, result);
        if( create > 0 ) create = edl->session->auto_keyframes;
        if( create && (!result || result->is_default ||
-              !EQUIV(track->from_units(result->position), position)) ) {
+           !EQUIV(track->from_units(result->position), position)) ) {
 //printf("Autos::get_auto_for_editing %p %p %p\n", default_auto, first, result);
                position = edl->align_to_frame(position, 0);
                result = insert_auto(track->to_units(position, 0));
@@ -383,10 +384,11 @@ Auto* Autos::insert_auto(int64_t position, Auto *templ)
 // Set curve mode
                if( !templ && result->is_floatauto() ) {
                        FloatAuto *floatauto = (FloatAuto *)result;
-                       floatauto->curve_mode =
+                       FloatAuto::t_mode new_mode =
                                edl->local_session->playback_start >= 0 &&
                                edl->local_session->playback_end < 0 ? FloatAuto::SMOOTH :
                                        (FloatAuto::t_mode) edl->local_session->floatauto_type;
+                       floatauto->change_curve_mode(new_mode, 0);
                }
        }
        else
index ee53f63a9c21494b90afbe426229d6f378331232..dcb997d8b76f8e5744843bfe7f3aa303ccc07849 100644 (file)
@@ -61,6 +61,7 @@ public:
        int auto_exists_for_editing(double position);
 // Returns auto at exact position, null if non-existent. ignores autokeyframming and align on frames
        Auto* get_auto_at_position(double position = -1);
+       Auto* get_auto(int id);
 
 // Get keyframe for editing with creation
 // create: <0: always new keyframe, =0: no new keyframe, >0: auto keyframe
index 4688e7bc04cead9a205e6a0fd67288640dc10b25..3960340ac93f0b0638712d698af52633509e2aa4 100644 (file)
@@ -29,6 +29,7 @@
 #include "awindow.h"
 #include "awindowgui.h"
 #include "bccmodels.h"
+#include "bcdisplayinfo.h"
 #include "bchash.h"
 #include "bcsignals.h"
 #include "bctimer.h"
@@ -945,6 +946,11 @@ void AssetPicon::create_objects()
                if( asset->video_data ) {
                        if( mwindow->preferences->use_thumbnails ) {
                                gui->unlock_window();
+                               char string[BCTEXTLEN];
+                               sprintf(string, _("Reading %s"), name);
+                               mwindow->gui->lock_window("AssetPicon::create_objects");
+                               mwindow->gui->show_message(string);
+                               mwindow->gui->unlock_window();
                                File *file = mwindow->video_cache->check_out(asset,
                                        mwindow->edl,
                                        1);
@@ -968,11 +974,6 @@ void AssetPicon::create_objects()
                                                        asset->width, asset->height,
                                                        BC_RGB888, -1);
                                        }
-                                       { char string[BCTEXTLEN];
-                                       sprintf(string, _("Reading %s"), name);
-                                       mwindow->gui->lock_window("AssetPicon::create_objects");
-                                       mwindow->gui->show_message(string);
-                                       mwindow->gui->unlock_window(); }
                                        file->read_frame(gui->temp_picon);
                                        mwindow->video_cache->check_in(asset);
 
@@ -2073,6 +2074,21 @@ void AWindowGUI::update_asset_list()
                        AssetPicon *picon = new AssetPicon(mwindow,
                                this, current);
                        new_assets.append(picon);
+                       if( current->width > ASSET_MAX_WIDTH || current->height > ASSET_MAX_HEIGHT ) {
+                               eprintf(_("Warning: %s\n"
+                                       " dimensions %dx%d exceed asset maximum limits %dx%d\n"),
+                                       current->path, current->width, current->height,
+                                               ASSET_MAX_WIDTH, ASSET_MAX_HEIGHT);
+                       }
+                       else if( mwindow->edl->session->playback_config->vconfig->driver == PLAYBACK_X11_GL ) {
+                               int texture_limit = BC_DisplayInfo::get_gl_max_texture_size();
+                               if( texture_limit >= 0 &&
+                                   (current->width >= texture_limit || current->height >= texture_limit) ) {
+                                       eprintf(_("Warning: %s\n"
+                                               " dimensions %dx%d exceed OpenGL texture limit %d\n"),
+                                               current->path, current->width, current->height, texture_limit);
+                               }
+                       }
                }
        }
 
index 8a3b22b2be50d22ec05a33b6f53d0f00b247e602..9fc3355afe2848387d03d243240b5b6b757894a2 100644 (file)
@@ -230,56 +230,36 @@ void BRender::allocate_map(int64_t brender_start, int64_t start, int64_t end)
 
 int BRender::set_video_map(int64_t position, int value)
 {
-       int update_gui = 0;
+//printf("BRender::set_video_map(%jd, %d)\n", position, value);
        map_lock->lock("BRender::set_video_map");
 
-
        if(value == BRender::NOT_SCANNED)
        {
                printf(_("BRender::set_video_map called to set NOT_SCANNED\n"));
        }
-
-// Preroll
-       if(position < 0)
-       {
-               ;
-       }
-       else
-// In range
-       if(position < map_size)
-       {
-               map[position] = value;
-       }
-       else
-// Obsolete EDL
-       {
+       if( position < 0) {} // Preroll
+       else if( position < map_size ) map[position] = value; // In range
+       else // Obsolete EDL
                printf(_("BRender::set_video_map %jd: attempt to set beyond end of map %jd.\n"),
                        position, map_size);
-       }
 
+       int update_gui = 0;
 // Maintain last contiguous here to reduce search time
-       if(position == last_contiguous && last_contiguous < map_size )
-       {
-               int i;
-               for(i = position + 1; i < map_size && map[i]; i++)
-               {
-                       ;
-               }
-               last_contiguous = i;
+       if( position == last_contiguous && last_contiguous < map_size ) {
+               while( last_contiguous < map_size && map[last_contiguous] )
+                       ++last_contiguous;
+               if( last_contiguous >= map_size ) update_gui = 1;
                mwindow->session->brender_end = (double)last_contiguous /
                        mwindow->edl->session->frame_rate;
 
-               if(timer->get_difference() > 1000 || last_contiguous >= map_size)
-               {
-                       update_gui = 1;
-                       timer->update();
-               }
        }
+       if( timer->get_difference() > 1000 )
+               update_gui = 1;
 
        map_lock->unlock();
 
-       if(update_gui)
-       {
+       if( update_gui ) {
+               timer->update();
                mwindow->gui->lock_window("BRender::set_video_map");
                mwindow->gui->update_timebar(1);
                mwindow->gui->unlock_window();
index 80bf347b677a49d9aee95d011514719aa814f799..a93f1e1b994f7d800ad08d61e8e3deeff11f74c7 100644 (file)
@@ -253,36 +253,29 @@ int CICache::get_oldest()
 int CICache::delete_oldest()
 {
        int result = 0;
-       total_lock->lock("CICache::delete_oldest");
        CICacheItem *oldest = 0;
-// at least 2
-       if( first != last ) {
-               oldest = first;
-               CICacheItem *current = oldest->next;
-               while( current ) {
+       total_lock->lock("CICache::delete_oldest");
+       if( first != last ) { // at least 2
+               CICacheItem *current = first;
+               for( ; !oldest && current; current=current->next )
+                       if( !current->checked_out ) oldest = current;
+               for( ; current; current=current->next ) {
+                       if( current->checked_out ) continue;
                        if( current->age < oldest->age )
                                oldest = current;
-                       current = current->next;
+               }
+// delete oldest of at least 2 cache files
+               if( oldest ) {
+                       remove_pointer(oldest);
+                       result = 1;
                }
        }
 // settle for just deleting one frame
-       else if( first )
+       else if( first && !first->checked_out )
                result = first->file->delete_oldest();
-       if( oldest ) {
-// Got the oldest file.  Try requesting cache purge from it.
-               if( oldest->file )
-                       oldest->file->purge_cache();
-// Delete the file if cache already empty and not checked out.
-               if( !oldest->checked_out )
-                       remove_pointer(oldest);
-               else
-                       oldest = 0;
-       }
        total_lock->unlock();
-       if( oldest ) {
+       if( oldest )
                oldest->Garbage::remove_user();
-               result = 1;
-       }
        return result;
 }
 
index 348817c4bac2915f44f10dd963d3e1ade73bba37..fd796bfcaef64b158ad34396ecb75e58a8f7a7e3 100644 (file)
@@ -156,7 +156,6 @@ ColorGUI::ColorGUI(BC_WindowBase *window)
        hue = 0; sat = 0; val = 0;
        red = 0; grn = 0; blu = 0;
        lum = 0; c_r = 0; c_b = 0;
-       alpha = 0;
 
        hsv_h = 0;  hsv_s = 0;  hsv_v = 0;
        rgb_r = 0;  rgb_g = 0;  rgb_b = 0;
@@ -1451,7 +1450,8 @@ void ColorBoxButton::create_objects()
 void ColorBoxButton::set_color(int color)
 {
        this->color = (color & 0xffffff);
-       this->alpha = (~color>>24) & 0xff;
+       if( this->alpha >= 0 )
+               this->alpha = (~color>>24) & 0xff;
        int r = (color>>16) & 0xff;
        int g = (color>> 8) & 0xff;
        int b = (color>> 0) & 0xff;
@@ -1513,7 +1513,8 @@ void ColorCircleButton::create_objects()
 void ColorCircleButton::set_color(int color)
 {
        this->color = (color & 0xffffff);
-       this->alpha = (~color>>24) & 0xff;
+       if( this->alpha >= 0 )
+               this->alpha = (~color>>24) & 0xff;
        int r = (color>>16) & 0xff;
        int g = (color>>8) & 0xff;
        int b = (color>>0) & 0xff;
index 5c2ed20785be62ff25f1efbef060320dfdb89f67..9416cee9ba6b3b4735814495e427b5ed6cc6dc63 100644 (file)
@@ -190,7 +190,8 @@ void CWindow::calculate_affected_autos(Track *track,
        if( y_auto )
                *y_auto = (FloatAuto*) calculate_affected_auto(track->automation->autos[iy],
                                create_y, &y_created, redraw);
-       if( z_auto ) *z_auto = (FloatAuto*) calculate_affected_auto(track->automation->autos[iz],
+       if( z_auto )
+               *z_auto = (FloatAuto*) calculate_affected_auto(track->automation->autos[iz],
                                create_z, &z_created, redraw);
 }
 
index 6ac2035c0bb9956f86b2cd741cda4d476cbf0580..560b079e448b4eb7e0cffbd7fee30532e9fc2bdb 100644 (file)
@@ -3054,9 +3054,13 @@ int CWindowCanvas::test_bezier(int button_press,
                                redraw = 1;
                        }
 
-                       float x_val = gui->affected_x->get_value();
-                       float y_val = gui->affected_y->get_value();
-                       float z_val = gui->affected_z->get_value();
+                       CWindowToolGUI *tool_gui = !gui->tool_panel ? 0 : gui->tool_panel->tool_gui;
+                       int edge = tool_gui ? tool_gui->edge : 0;
+                       int span = tool_gui ? tool_gui->span : 0;
+
+                       float x_val = gui->affected_x->get_value(edge);
+                       float y_val = gui->affected_y->get_value(edge);
+                       float z_val = gui->affected_z->get_value(edge);
 
                        if( gui->translating_zoom ) {
                                float z = gui->center_z + (cursor_y - gui->y_origin) / yS(128);
@@ -3066,7 +3070,7 @@ int CWindowCanvas::test_bezier(int button_press,
                                        redraw = 1;
                                        redraw_canvas = 1;
                                }
-                               gui->affected_z->set_value(z);
+                               gui->affected_z->bump_value(z, edge, span);
                        }
                        else {
                                float dx = cursor_x - gui->x_origin;
@@ -3077,8 +3081,8 @@ int CWindowCanvas::test_bezier(int button_press,
                                }
                                float x = gui->center_x + dx;
                                float y = gui->center_y + dy;
-                               gui->affected_x->set_value(x);
-                               gui->affected_y->set_value(y);
+                               gui->affected_x->bump_value(x, edge, span);
+                               gui->affected_y->bump_value(y, edge, span);
                                if( !EQUIV(x_val, x) || !EQUIV(y_val, y) ) {
                                        rerender = 1;
                                        redraw = 1;
index 55d64b4504a871d9588508618ed8fd17618f640b..c0fc37cc3cf0272f6c64f1b4ac0f892cd8a8a6c4 100644 (file)
@@ -273,6 +273,7 @@ CWindowToolGUI::CWindowToolGUI(MWindow *mwindow,
        this->mwindow = mwindow;
        this->thread = thread;
        current_operation = 0;
+       span = 1;  edge = 0;
 }
 
 CWindowToolGUI::~CWindowToolGUI()
@@ -327,6 +328,23 @@ int CWindowToolGUI::translation_event()
        return 0;
 }
 
+void CWindowToolGUI::update_auto(Track *track, int idx, CWindowCoord *vp)
+{
+       FloatAuto *float_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
+                       track->automation->autos[idx], 1);
+       if( !float_auto ) return;
+       float v = float_auto->get_value(edge);
+       float t = atof(vp->get_text());
+       if( v == t ) return;
+       float_auto->bump_value(t, edge, span);
+       if( idx == AUTOMATION_PROJECTOR_Z || idx == AUTOMATION_CAMERA_Z ) {
+               mwindow->gui->lock_window("CWindowToolGUI::update_auto");
+               mwindow->gui->draw_overlays(1);
+               mwindow->gui->unlock_window();
+       }
+       update();
+       update_preview();
+}
 
 void CWindowToolGUI::update_preview(int changed_edl)
 {
@@ -821,30 +839,27 @@ struct _CVD {
        const char* tooltip;
 };
 
-const _CVD Camera_Crv_Smooth =
-       {       FloatAuto::SMOOTH,
-               true,
-               "tan_smooth",
-               N_("\"smooth\" Curve on current Camera Keyframes")
-       };
-const _CVD Camera_Crv_Linear =
-       {       FloatAuto::LINEAR,
-               true,
-               "tan_linear",
-               N_("\"linear\" Curve on current Camera Keyframes")
-       };
-const _CVD Projector_Crv_Smooth =
-       {       FloatAuto::SMOOTH,
-               false,
-               "tan_smooth",
-               N_("\"smooth\" Curve on current Projector Keyframes")
-       };
-const _CVD Projector_Crv_Linear =
-       {       FloatAuto::LINEAR,
-               false,
-               "tan_linear",
-               N_("\"linear\" Curve on current Projector Keyframes")
-       };
+const _CVD Camera_Crv_Smooth = { FloatAuto::SMOOTH, true, "tan_smooth",
+               N_("\"smooth\" Curve on current Camera Keyframes") };
+const _CVD Camera_Crv_Linear = { FloatAuto::LINEAR, true, "tan_linear",
+               N_("\"linear\" Curve on current Camera Keyframes") };
+const _CVD Camera_Crv_Tangent = { FloatAuto::TFREE, true, "tan_tangent",
+               N_("\"tangent\" Curve on current Camera Keyframes") };
+const _CVD Camera_Crv_Free  = { FloatAuto::FREE, true, "tan_free",
+               N_("\"free\" Curve on current Camera Keyframes") };
+const _CVD Camera_Crv_Bump = { FloatAuto::BUMP, true, "tan_bump",
+               N_("\"bump\" Curve on current Camera Keyframes") };
+
+const _CVD Projector_Crv_Smooth = { FloatAuto::SMOOTH, false, "tan_smooth",
+               N_("\"smooth\" Curve on current Projector Keyframes") };
+const _CVD Projector_Crv_Linear = { FloatAuto::LINEAR, false, "tan_linear",
+               N_("\"linear\" Curve on current Projector Keyframes") };
+const _CVD Projector_Crv_Tangent = { FloatAuto::TFREE, false, "tan_tangent",
+               N_("\"tangent\" Curve on current Projector Keyframes") };
+const _CVD Projector_Crv_Free  = { FloatAuto::FREE, false, "tan_free",
+               N_("\"free\" Curve on current Projector Keyframes") };
+const _CVD Projector_Crv_Bump = { FloatAuto::BUMP, false, "tan_bump",
+               N_("\"bump\" Curve on current Projector Keyframes") };
 
 // Implementation Class für Keyframe Curve Mode buttons
 //
@@ -857,17 +872,19 @@ const _CVD Projector_Crv_Linear =
 class CWindowCurveToggle : public BC_Toggle
 {
 public:
-       CWindowCurveToggle(_CVD mode, MWindow *mwindow, CWindowToolGUI *gui, int x, int y);
+       CWindowCurveToggle(const _CVD &mode,
+                       MWindow *mwindow, CWindowToolGUI *gui, int x, int y);
        void check_toggle_state(FloatAuto *x, FloatAuto *y, FloatAuto *z);
        int handle_event();
 private:
-       _CVD cfg;
+       const _CVD &cfg;
        MWindow *mwindow;
        CWindowToolGUI *gui;
 };
 
 
-CWindowCurveToggle::CWindowCurveToggle(_CVD mode, MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
+CWindowCurveToggle::CWindowCurveToggle(const _CVD &mode,
+                       MWindow *mwindow, CWindowToolGUI *gui, int x, int y)
  : BC_Toggle(x, y, mwindow->theme->get_image_set(mode.icon_id), false),
    cfg(mode)
 {
@@ -941,6 +958,7 @@ void CWindowCameraGUI::create_objects()
        FloatAuto *x_auto = 0, *y_auto = 0, *z_auto = 0;
        BC_Title *title;
        BC_Button *button;
+       span = 1;  edge = 0;
 
        lock_window("CWindowCameraGUI::create_objects");
        if( track ) {
@@ -978,9 +996,15 @@ void CWindowCameraGUI::create_objects()
        add_subwindow(button = new CWindowCameraRight(mwindow, this, x1, y));
 // additional Buttons to control the curve mode of the "current" keyframe
        x1 += button->get_w() + xs15;
-       add_subwindow(this->t_smooth = new CWindowCurveToggle(Camera_Crv_Smooth, mwindow, this, x1, y));
-       x1 += button->get_w() + xs10;
-       add_subwindow(this->t_linear = new CWindowCurveToggle(Camera_Crv_Linear, mwindow, this, x1, y));
+       add_subwindow(t_smooth = new CWindowCurveToggle(Camera_Crv_Smooth, mwindow, this, x1, y));
+       x1 += t_smooth->get_w() + xs10;
+       add_subwindow(t_linear = new CWindowCurveToggle(Camera_Crv_Linear, mwindow, this, x1, y));
+       x1 += t_linear->get_w() + xs10;
+       add_subwindow(t_tangent = new CWindowCurveToggle(Camera_Crv_Tangent, mwindow, this, x1, y));
+       x1 += t_tangent->get_w() + xs10;
+       add_subwindow(t_free = new CWindowCurveToggle(Camera_Crv_Free, mwindow, this, x1, y));
+       x1 += t_free->get_w() + xs10;
+       add_subwindow(t_bump = new CWindowCurveToggle(Camera_Crv_Bump, mwindow, this, x1, y));
 
        y += button->get_h();
        x1 = xs10;
@@ -990,9 +1014,13 @@ void CWindowCameraGUI::create_objects()
        x1 += button->get_w();
        add_subwindow(button = new CWindowCameraBottom(mwindow, this, x1, y));
        x1 += button->get_w() + xs15;
-       add_subwindow(this->add_keyframe = new CWindowCameraAddKeyframe(mwindow, this, x1, y));
-       x1 += button->get_w() + xs10;
-       add_subwindow(this->reset = new CWindowCameraReset(mwindow, this, x1, y));
+       add_subwindow(add_keyframe = new CWindowCameraAddKeyframe(mwindow, this, x1, y));
+       x1 += add_keyframe->get_w() + xs15;
+       add_subwindow(auto_edge = new CWindowCurveAutoEdge(mwindow, this, x1, y));
+       x1 += auto_edge->get_w() + xs10;
+       add_subwindow(auto_span = new CWindowCurveAutoSpan(mwindow, this, x1, y));
+       x1 += auto_span->get_w() + xs15;
+       add_subwindow(reset = new CWindowCameraReset(mwindow, this, x1, y));
 
 // fill in current auto keyframe values, set toggle states.
        this->update();
@@ -1001,62 +1029,16 @@ void CWindowCameraGUI::create_objects()
 
 void CWindowCameraGUI::handle_event()
 {
-       FloatAuto *x_auto = 0;
-       FloatAuto *y_auto = 0;
-       FloatAuto *z_auto = 0;
        Track *track = mwindow->cwindow->calculate_affected_track();
-       if(track)
-       {
-               mwindow->undo->update_undo_before(_("camera"), this);
-               if(event_caller == x)
-               {
-                       x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
-                               track->automation->autos[AUTOMATION_CAMERA_X], 1);
-                       if(x_auto)
-                       {
-                               x_auto->set_value(atof(x->get_text()));
-                               update();
-                               update_preview();
-                       }
-               }
-               else
-               if(event_caller == y)
-               {
-                       y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
-                               track->automation->autos[AUTOMATION_CAMERA_Y], 1);
-                       if(y_auto)
-                       {
-                               y_auto->set_value(atof(y->get_text()));
-                               update();
-                               update_preview();
-                       }
-               }
-               else
-               if(event_caller == z)
-               {
-                       z_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
-                               track->automation->autos[AUTOMATION_CAMERA_Z], 1);
-                       if(z_auto)
-                       {
-                               float zoom = atof(z->get_text());
-                               if(zoom > 100.) zoom = 100.;
-                               else
-                               if(zoom < 0.01) zoom = 0.01;
-       // Doesn't allow user to enter from scratch
-       //              if(zoom != atof(z->get_text()))
-       //                      z->update(zoom);
-
-                               z_auto->set_value(zoom);
-                               mwindow->gui->lock_window("CWindowCameraGUI::handle_event");
-                               mwindow->gui->draw_overlays(1);
-                               mwindow->gui->unlock_window();
-                               update();
-                               update_preview();
-                       }
-               }
-
-               mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
-       }
+       if( !track ) return;
+       mwindow->undo->update_undo_before(_("camera"), this);
+       if( event_caller == x )
+               update_auto(track, AUTOMATION_CAMERA_X, x);
+       else if( event_caller == y )
+               update_auto(track, AUTOMATION_CAMERA_Y, y);
+       else if( event_caller == z )
+               update_auto(track, AUTOMATION_CAMERA_Z, z);
+       mwindow->undo->update_undo_after(_("camera"), LOAD_ALL);
 }
 
 void CWindowCameraGUI::update()
@@ -1065,21 +1047,32 @@ void CWindowCameraGUI::update()
        FloatAuto *y_auto = 0;
        FloatAuto *z_auto = 0;
        Track *track = mwindow->cwindow->calculate_affected_track();
+       int bg_color = get_resources()->text_background;
+       int hi_color = bg_color ^ 0x444444;
        if( track ) {
                mwindow->cwindow->calculate_affected_autos(track,
                        &x_auto, &y_auto, &z_auto, 1, 0, 0, 0);
        }
 
        if( x_auto ) {
-               float xvalue = x_auto->get_value();
+               int color = (edge || span) && x_auto->curve_mode == FloatAuto::BUMP ?
+                       hi_color : bg_color;
+               x->get_textbox()->set_back_color(color);
+               float xvalue = x_auto->get_value(edge);
                x->update_gui(xvalue);
        }
        if( y_auto ) {
-               float yvalue = y_auto->get_value();
+               int color = (edge || span) && y_auto->curve_mode == FloatAuto::BUMP ?
+                       hi_color : bg_color;
+               y->get_textbox()->set_back_color(color);
+               float yvalue = y_auto->get_value(edge);
                y->update_gui(yvalue);
        }
        if( z_auto ) {
-               float zvalue = z_auto->get_value();
+               int color = (edge || span) && z_auto->curve_mode == FloatAuto::BUMP ?
+                       hi_color : bg_color;
+               z->get_textbox()->set_back_color(color);
+               float zvalue = z_auto->get_value(edge);
                z->update_gui(zvalue);
                thread->gui->lock_window("CWindowCameraGUI::update");
                thread->gui->composite_panel->cpanel_zoom->update(zvalue);
@@ -1089,6 +1082,9 @@ void CWindowCameraGUI::update()
        if( x_auto && y_auto && z_auto ) {
                t_smooth->check_toggle_state(x_auto, y_auto, z_auto);
                t_linear->check_toggle_state(x_auto, y_auto, z_auto);
+               t_tangent->check_toggle_state(x_auto, y_auto, z_auto);
+               t_free->check_toggle_state(x_auto, y_auto, z_auto);
+               t_bump->check_toggle_state(x_auto, y_auto, z_auto);
        }
 }
 
@@ -1335,6 +1331,38 @@ int CWindowCameraReset::handle_event()
        return gui->press(&CWindowCanvas::reset_camera);
 }
 
+CWindowCurveAutoEdge::CWindowCurveAutoEdge(MWindow *mwindow,
+               CWindowToolGUI *gui, int x, int y)
+ : BC_Toggle(x, y, mwindow->theme->get_image_set("bump_edge"), gui->edge)
+{
+       this->mwindow = mwindow;
+       this->gui = gui;
+       set_tooltip(_("Bump edit edge left/right"));
+}
+
+int CWindowCurveAutoEdge::handle_event()
+{
+       gui->edge = get_value();
+       gui->update();
+       return 1;
+}
+
+CWindowCurveAutoSpan::CWindowCurveAutoSpan(MWindow *mwindow,
+               CWindowToolGUI *gui, int x, int y)
+ : BC_Toggle(x, y, mwindow->theme->get_image_set("bump_span"), gui->span)
+{
+       this->mwindow = mwindow;
+       this->gui = gui;
+       set_tooltip(_("Bump spans to next/prev"));
+}
+
+int CWindowCurveAutoSpan::handle_event()
+{
+       gui->span = get_value();
+       gui->update();
+       return 1;
+}
+
 
 CWindowProjectorGUI::CWindowProjectorGUI(MWindow *mwindow, CWindowTool *thread)
  : CWindowToolGUI(mwindow, thread, _(PROGRAM_NAME ": Projector"), xS(340), yS(170))
@@ -1354,6 +1382,7 @@ void CWindowProjectorGUI::create_objects()
        FloatAuto *z_auto = 0;
        BC_Title *title;
        BC_Button *button;
+       span = 1;  edge = 0;
 
        lock_window("CWindowProjectorGUI::create_objects");
        if( track ) {
@@ -1390,9 +1419,15 @@ void CWindowProjectorGUI::create_objects()
        add_subwindow(button = new CWindowProjectorRight(mwindow, this, x1, y));
 // additional Buttons to control the curve mode of the "current" keyframe
        x1 += button->get_w() + xs15;
-       add_subwindow(this->t_smooth = new CWindowCurveToggle(Projector_Crv_Smooth, mwindow, this, x1, y));
-       x1 += button->get_w() + xs10;
-       add_subwindow(this->t_linear = new CWindowCurveToggle(Projector_Crv_Linear, mwindow, this, x1, y));
+       add_subwindow(t_smooth = new CWindowCurveToggle(Projector_Crv_Smooth, mwindow, this, x1, y));
+       x1 += t_smooth->get_w() + xs10;
+       add_subwindow(t_linear = new CWindowCurveToggle(Projector_Crv_Linear, mwindow, this, x1, y));
+       x1 += t_linear->get_w() + xs15;
+       add_subwindow(t_tangent = new CWindowCurveToggle(Projector_Crv_Tangent, mwindow, this, x1, y));
+       x1 += t_tangent->get_w() + xs10;
+       add_subwindow(t_free = new CWindowCurveToggle(Projector_Crv_Free, mwindow, this, x1, y));
+       x1 += t_free->get_w() + xs10;
+       add_subwindow(t_bump = new CWindowCurveToggle(Projector_Crv_Bump, mwindow, this, x1, y));
 
        y += button->get_h();
        x1 = xs10;
@@ -1402,9 +1437,13 @@ void CWindowProjectorGUI::create_objects()
        x1 += button->get_w();
        add_subwindow(button = new CWindowProjectorBottom(mwindow, this, x1, y));
        x1 += button->get_w() + xs15;
-       add_subwindow(this->add_keyframe = new CWindowProjectorAddKeyframe(mwindow, this, x1, y));
-       x1 += button->get_w() + xs10;
-       add_subwindow(this->reset = new CWindowProjectorReset(mwindow, this, x1, y));
+       add_subwindow(add_keyframe = new CWindowProjectorAddKeyframe(mwindow, this, x1, y));
+       x1 += add_keyframe->get_w() + xs15;
+       add_subwindow(auto_span = new CWindowCurveAutoSpan(mwindow, this, x1, y));
+       x1 += auto_span->get_w() + xs10;
+       add_subwindow(auto_edge = new CWindowCurveAutoEdge(mwindow, this, x1, y));
+       x1 += auto_edge->get_w() + xs15;
+       add_subwindow(reset = new CWindowProjectorReset(mwindow, this, x1, y));
 
 // fill in current auto keyframe values, set toggle states.
        this->update();
@@ -1413,61 +1452,16 @@ void CWindowProjectorGUI::create_objects()
 
 void CWindowProjectorGUI::handle_event()
 {
-       FloatAuto *x_auto = 0;
-       FloatAuto *y_auto = 0;
-       FloatAuto *z_auto = 0;
        Track *track = mwindow->cwindow->calculate_affected_track();
-
-       if(track)
-       {
-               mwindow->undo->update_undo_before(_("projector"), this);
-               if(event_caller == x)
-               {
-                       x_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
-                               track->automation->autos[AUTOMATION_PROJECTOR_X], 1);
-                       if(x_auto)
-                       {
-                               x_auto->set_value(atof(x->get_text()));
-                               update();
-                               update_preview();
-                       }
-               }
-               else
-               if(event_caller == y)
-               {
-                       y_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
-                               track->automation->autos[AUTOMATION_PROJECTOR_Y], 1);
-                       if(y_auto)
-                       {
-                               y_auto->set_value(atof(y->get_text()));
-                               update();
-                               update_preview();
-                       }
-               }
-               else
-               if(event_caller == z)
-               {
-                       z_auto = (FloatAuto*)mwindow->cwindow->calculate_affected_auto(
-                               track->automation->autos[AUTOMATION_PROJECTOR_Z], 1);
-                       if(z_auto)
-                       {
-                               float zoom = atof(z->get_text());
-                               if(zoom > 100.) zoom = 100.;
-                               else if(zoom < 0.01) zoom = 0.01;
-//                     if (zoom != atof(z->get_text()))
-//                             z->update(zoom);
-                               z_auto->set_value(zoom);
-
-                               mwindow->gui->lock_window("CWindowProjectorGUI::handle_event");
-                               mwindow->gui->draw_overlays(1);
-                               mwindow->gui->unlock_window();
-
-                               update();
-                               update_preview();
-                       }
-               }
-               mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
-       }
+       if( !track ) return;
+       mwindow->undo->update_undo_before(_("projector"), this);
+       if( event_caller == x )
+               update_auto(track, AUTOMATION_PROJECTOR_X, x);
+       else if( event_caller == y )
+               update_auto(track, AUTOMATION_PROJECTOR_Y, y);
+       else if( event_caller == z )
+               update_auto(track, AUTOMATION_PROJECTOR_Z, z);
+       mwindow->undo->update_undo_after(_("projector"), LOAD_ALL);
 }
 
 void CWindowProjectorGUI::update()
@@ -1476,21 +1470,32 @@ void CWindowProjectorGUI::update()
        FloatAuto *y_auto = 0;
        FloatAuto *z_auto = 0;
        Track *track = mwindow->cwindow->calculate_affected_track();
+       int bg_color = get_resources()->text_background;
+       int hi_color = bg_color ^ 0x444444;
        if( track ) {
                mwindow->cwindow->calculate_affected_autos(track,
                        &x_auto, &y_auto, &z_auto, 0, 0, 0, 0);
        }
 
        if( x_auto ) {
-               float xvalue = x_auto->get_value();
+               int color = (edge || span) && x_auto->curve_mode == FloatAuto::BUMP ?
+                       hi_color : bg_color;
+               x->get_textbox()->set_back_color(color);
+               float xvalue = x_auto->get_value(edge);
                x->update_gui(xvalue);
        }
        if( y_auto ) {
-               float yvalue = y_auto->get_value();
+               int color = (edge || span) && y_auto->curve_mode == FloatAuto::BUMP ?
+                       hi_color : bg_color;
+               y->get_textbox()->set_back_color(color);
+               float yvalue = y_auto->get_value(edge);
                y->update_gui(yvalue);
        }
        if( z_auto ) {
-               float zvalue = z_auto->get_value();
+               int color = (edge || span) && z_auto->curve_mode == FloatAuto::BUMP ?
+                       hi_color : bg_color;
+               z->get_textbox()->set_back_color(color);
+               float zvalue = z_auto->get_value(edge);
                z->update_gui(zvalue);
                thread->gui->lock_window("CWindowProjectorGUI::update");
                thread->gui->composite_panel->cpanel_zoom->update(zvalue);
@@ -1500,6 +1505,9 @@ void CWindowProjectorGUI::update()
        if( x_auto && y_auto && z_auto ) {
                t_smooth->check_toggle_state(x_auto, y_auto, z_auto);
                t_linear->check_toggle_state(x_auto, y_auto, z_auto);
+               t_tangent->check_toggle_state(x_auto, y_auto, z_auto);
+               t_free->check_toggle_state(x_auto, y_auto, z_auto);
+               t_bump->check_toggle_state(x_auto, y_auto, z_auto);
        }
 }
 
index 00e485e3c4cde4b90bda439e79d3a10539d0323f..942651f2fbeab4d9ba230638523b0137c680b4c4 100644 (file)
@@ -93,6 +93,7 @@ public:
 
 // Update EDL and preview only
        void update_preview(int changed_edl=0);
+       void update_auto(Track *track, int idx, CWindowCoord *vp);
        void draw_preview(int changed_edl);
        int current_operation;
        virtual int close_event();
@@ -103,6 +104,7 @@ public:
        MWindow *mwindow;
        CWindowTool *thread;
        CWindowCoord *event_caller;
+       int edge, span;
 };
 
 class CWindowCoord : public BC_TumbleTextBox
@@ -144,6 +146,26 @@ public:
        CWindowCoord *coord;
 };
 
+class CWindowCurveAutoEdge : public BC_Toggle
+{
+public:
+       CWindowCurveAutoEdge(MWindow *mwindow, CWindowToolGUI *gui, int x, int y);
+       int handle_event();
+
+       MWindow *mwindow;
+       CWindowToolGUI *gui;
+};
+
+class CWindowCurveAutoSpan : public BC_Toggle
+{
+public:
+       CWindowCurveAutoSpan(MWindow *mwindow, CWindowToolGUI *gui, int x, int y);
+
+       int handle_event();
+       MWindow *mwindow;
+       CWindowToolGUI *gui;
+};
+
 
 class CWindowCropApply : public BC_GenericButton
 {
@@ -795,7 +817,9 @@ public:
        CWindowCoord *x, *y, *z;
        CWindowCameraAddKeyframe *add_keyframe;
        CWindowCameraReset *reset;
-       CWindowCurveToggle *t_smooth, *t_linear;
+       CWindowCurveToggle *t_smooth, *t_linear, *t_tangent, *t_free, *t_bump;
+       CWindowCurveAutoSpan *auto_span;
+       CWindowCurveAutoEdge *auto_edge;
 };
 
 class CWindowCameraLeft : public BC_Button
@@ -891,7 +915,9 @@ public:
        CWindowCoord *x, *y, *z;
        CWindowProjectorAddKeyframe *add_keyframe;
        CWindowProjectorReset *reset;
-       CWindowCurveToggle *t_smooth, *t_linear;
+       CWindowCurveToggle *t_smooth, *t_linear, *t_tangent, *t_free, *t_bump;
+       CWindowCurveAutoSpan *auto_span;
+       CWindowCurveAutoEdge *auto_edge;
 };
 
 class CWindowProjectorLeft : public BC_Button
index af53c37882f5b8e67334ee1e5b0c05c140e57caa..4124fc03c2efb9479e8399bd85d47b47b33eaf3e 100644 (file)
@@ -27,6 +27,8 @@ class CWindowToolGUI;
 class CWindowCoord;
 class CWindowCoordSlider;
 class CWindowCoordRange;
+class CWindowCurveAutoEdge;
+class CWindowCurveAutoSpan;
 class CWindowCropApply;
 class CWindowCropOpMode;
 class CWindowCropOpItem;
index 1f75414f45a68d668661f96a24e3cbca3af9c4e5..bf33acba43bf1dce3e4af4d0215bf26fe9547223 100644 (file)
@@ -1127,7 +1127,7 @@ EditUndo::EditUndo(MWindow *mwindow, EditPanel *panel, int x, int y)
 {
        this->mwindow = mwindow;
        this->panel = panel;
-       set_tooltip(_("Undo ( z )"));
+       set_tooltip(_("Undo ( z or Ctrl-z)"));
 }
 EditUndo::~EditUndo()
 {
index da9b06ba4cb84d5b60c08acf376461e166ff1e8e..60dcafb8ae8a09a5814ca423e8a275f1029ad350 100644 (file)
@@ -67,6 +67,7 @@ void EditPopup::create_objects()
 {
        add_item(open_edl = new EditPopupOpenEDL(mwindow, this));
        add_item(new EditPopupClearSelect(mwindow, this));
+       add_item(new EditPopupSelectEdits(mwindow, this));
        add_item(new EditPopupCopy(mwindow, this));
        add_item(new EditPopupCut(mwindow, this));
        add_item(new EditPopupMute(mwindow, this));
@@ -159,6 +160,21 @@ int EditPopupClearSelect::handle_event()
        return 1;
 }
 
+EditPopupSelectEdits::EditPopupSelectEdits(MWindow *mwindow, EditPopup *popup)
+ : BC_MenuItem(_("Select Edits"),_("Ctrl-Alt-a"),'a')
+{
+       this->mwindow = mwindow;
+       this->popup = popup;
+       set_ctrl(1);
+       set_alt(1);
+}
+
+int EditPopupSelectEdits::handle_event()
+{
+       mwindow->select_edits();
+       return 1;
+}
+
 EditPopupCopy::EditPopupCopy(MWindow *mwindow, EditPopup *popup)
  : BC_MenuItem(_("Copy"),_("Ctrl-c"),'c')
 {
@@ -203,11 +219,12 @@ int EditPopupCut::handle_event()
 }
 
 EditPopupCutPack::EditPopupCutPack(MWindow *mwindow, EditPopup *popup)
- : BC_MenuItem(_("Cut pack"),_("Ctrl-z"),'z')
+ : BC_MenuItem(_("Cut pack"),_("Ctrl-Alt-z"),'z')
 {
        this->mwindow = mwindow;
        this->popup = popup;
        set_ctrl(1);
+       set_alt();
 }
 
 int EditPopupCutPack::handle_event()
index 2c34be62489d2e0864f2db30aedabe26ecc52e4c..ed3fe2f8c09e2de5b68ef8002e3295c7089b56d7 100644 (file)
@@ -73,6 +73,16 @@ public:
        EditPopup *popup;
 };
 
+class EditPopupSelectEdits : public BC_MenuItem
+{
+public:
+       EditPopupSelectEdits(MWindow *mwindow, EditPopup *popup);
+       int handle_event();
+
+       MWindow *mwindow;
+       EditPopup *popup;
+};
+
 class EditPopupCopy : public BC_MenuItem
 {
 public:
index cec86c847d449255a2441fcd0fa8070becc54697..71dd3b18e293ad41af189f0d9f161ceb1f010822 100644 (file)
@@ -560,6 +560,13 @@ Edit* Edits::editof(int64_t position, int direction, int use_nudge)
        return 0;     // return 0 on failure
 }
 
+Edit* Edits::get_edit(int id)
+{
+       Edit *current = first;
+       while( current && current->orig_id != id ) current = NEXT;
+       return current;
+}
+
 Edit* Edits::get_playable_edit(int64_t position, int use_nudge)
 {
        Edit *current;
index bd73e4e79d7b352de75775951e7f984370e65428..5550cb5572e8fb935d7f4b7d2dad9d23d7edb3d2 100644 (file)
@@ -109,6 +109,7 @@ public:
 // ==================================== accounting
 
        Edit* editof(int64_t position, int direction, int use_nudge);
+       Edit* get_edit(int id);
 // Return an edit if position is over an edit and the edit has a source file
        Edit* get_playable_edit(int64_t position, int use_nudge);
 //     int64_t total_length();
index ff56d686877ff6244529ea407acd07044304a67a..966eef59816ee7d524a895402b3da18041f31ea5 100644 (file)
@@ -125,6 +125,8 @@ class EDL;
 #define ASSETS_ICON_LIST 3
 #define FOLDERS_TEXT 0
 #define FOLDERS_ICONS 1
+#define ASSET_MAX_WIDTH 32767
+#define ASSET_MAX_HEIGHT 32767
 
 #define ASSET_COLUMNS 2
 
index 673ec070f77bb563f8a89e0c8c6d6600d24a42f8..f3044f6d64aca49bad91b9ab86f2235c7771b801 100644 (file)
@@ -75,7 +75,6 @@ EDLSession::EDLSession(EDL *edl)
        cwindow_zoom = 1.0;
        cwindow_click2play = 0;
        cwindow_clear_color = BLACK;
-       cwindow_clear_alpha = 0;
        strcpy(default_atransition, INIT_ATRANSITION);
        strcpy(default_vtransition, INIT_VTRANSITION);
        default_transition_length = 1.0;
@@ -184,8 +183,7 @@ int EDLSession::need_rerender(EDLSession *ptr)
                (proxy_disabled_scale != ptr->proxy_disabled_scale) ||
                (proxy_scale != ptr->proxy_scale) ||
                (proxy_use_scaler != ptr->proxy_use_scaler) ||
-               (cwindow_clear_color != ptr->cwindow_clear_color) ||
-               (cwindow_clear_alpha != ptr->cwindow_clear_alpha));
+               (cwindow_clear_color != ptr->cwindow_clear_color));
 }
 
 void EDLSession::equivalent_output(EDLSession *session, double *result)
@@ -262,7 +260,6 @@ int EDLSession::load_defaults(BC_Hash *defaults)
        cwindow_zoom = defaults->get("CWINDOW_ZOOM", (float)1);
        cwindow_click2play = defaults->get("CWINDOW_CLICK2PLAY", 0);
        cwindow_clear_color = defaults->get("CWINDOW_CLEAR_COLOR", BLACK);
-       cwindow_clear_alpha = defaults->get("CWINDOW_CLEAR_ALPHA", 0);
        sprintf(default_atransition, INIT_ATRANSITION);
        defaults->get("DEFAULT_ATRANSITION", default_atransition);
        sprintf(default_vtransition, INIT_VTRANSITION);
@@ -413,7 +410,6 @@ int EDLSession::save_defaults(BC_Hash *defaults)
        defaults->update("CWINDOW_ZOOM", cwindow_zoom);
        defaults->update("CWINDOW_CLICK2PLAY", cwindow_click2play);
        defaults->update("CWINDOW_CLEAR_COLOR", cwindow_clear_color);
-       defaults->update("CWINDOW_CLEAR_ALPHA", cwindow_clear_alpha);
        defaults->update("DEFAULT_ATRANSITION", default_atransition);
        defaults->update("DEFAULT_VTRANSITION", default_vtransition);
        defaults->update("DEFAULT_TRANSITION_LENGTH", default_transition_length);
@@ -641,7 +637,6 @@ int EDLSession::load_xml(FileXML *file,
                cwindow_zoom = file->tag.get_property("CWINDOW_ZOOM", cwindow_zoom);
                cwindow_click2play = file->tag.get_property("CWINDOW_CLICK2PLAY", cwindow_click2play);
                cwindow_clear_color = file->tag.get_property("CWINDOW_CLEAR_COLOR", cwindow_clear_color);
-               cwindow_clear_alpha = file->tag.get_property("CWINDOW_CLEAR_ALPHA", cwindow_clear_alpha);
                editing_mode = file->tag.get_property("EDITING_MODE", editing_mode);
                folderlist_format = file->tag.get_property("FOLDERLIST_FORMAT", folderlist_format);
                highlighted_track = file->tag.get_property("HIGHLIGHTED_TRACK", 0);
@@ -712,7 +707,6 @@ int EDLSession::save_xml(FileXML *file)
        file->tag.set_property("CWINDOW_ZOOM", cwindow_zoom);
        file->tag.set_property("CWINDOW_CLICK2PLAY", cwindow_click2play);
        file->tag.set_property("CWINDOW_CLEAR_COLOR", cwindow_clear_color);
-       file->tag.set_property("CWINDOW_CLEAR_ALPHA", cwindow_clear_alpha);
        file->tag.set_property("EDITING_MODE", editing_mode);
        file->tag.set_property("FOLDERLIST_FORMAT", folderlist_format);
        file->tag.set_property("HIGHLIGHTED_TRACK", highlighted_track);
@@ -851,7 +845,6 @@ int EDLSession::copy(EDLSession *session)
        cwindow_zoom = session->cwindow_zoom;
        cwindow_click2play = session->cwindow_click2play;
        cwindow_clear_color = session->cwindow_clear_color;
-       cwindow_clear_alpha = session->cwindow_clear_alpha;
        strcpy(default_atransition, session->default_atransition);
        strcpy(default_vtransition, session->default_vtransition);
        default_transition_length = session->default_transition_length;
index eebe71f2bac092bcfb9a3c3564a8773f7796e69f..fad4789aaa6b5388e31f61522c4f3f39a97a9469 100644 (file)
@@ -121,7 +121,6 @@ public:
        int cwindow_click2play;
 // CWindow clear color
        int cwindow_clear_color;
-       int cwindow_clear_alpha;
 // Transition
        char default_atransition[BCTEXTLEN];
        char default_vtransition[BCTEXTLEN];
index b3915cfc44de133644e71180239b519170199d2d..97b6698acbb2ffc342f93049dbd54537d0a39235 100644 (file)
@@ -270,7 +270,8 @@ FFStream::FFStream(FFMPEG *ffmpeg, AVStream *st, int fidx)
        frm_count = 0;
        nudge = AV_NOPTS_VALUE;
        seek_pos = curr_pos = 0;
-       seeked = 1;  eof = 0;
+       seeking = 0; seeked = 1;
+       eof = 0;
        reading = writing = 0;
        hw_pixfmt = AV_PIX_FMT_NONE;
        hw_device_ctx = 0;
@@ -714,6 +715,7 @@ int FFStream::seek(int64_t no, double rate)
                }
        }
        if( pos == curr_pos ) return 0;
+       seeking = -1;
        double secs = pos < 0 ? 0. : pos / rate;
        AVRational time_base = st->time_base;
        int64_t tstmp = time_base.num > 0 ? secs * time_base.den/time_base.num : 0;
@@ -1220,10 +1222,36 @@ int FFVideoStream::load(VFrame *vframe, int64_t pos)
                return -1;
        }
        int i = MAX_RETRY + pos - curr_pos;
+       int64_t cache_start = 0;
        while( ret>=0 && !flushed && curr_pos<=pos && --i>=0 ) {
                ret = read_frame(frame);
-               if( ret > 0 ) ++curr_pos;
+               if( ret > 0 ) {
+                       if( frame->key_frame && seeking < 0 ) {
+                               int use_cache = ffmpeg->get_use_cache();
+                               if( use_cache < 0 ) {
+// for reverse read, reload file frame_cache from keyframe to pos
+                                       ffmpeg->purge_cache();
+                                       int count = preferences->cache_size /
+                                               vframe->get_data_size() / 2;  // try to burn only 1/2 of cache
+                                       cache_start = pos - count + 1;
+                                       seeking = 1;
+                               }
+                               else
+                                       seeking = 0;
+                       }
+                       if( seeking > 0 && curr_pos >= cache_start && curr_pos < pos ) {
+                               int vw =vframe->get_w(), vh = vframe->get_h();
+                               int vcolor_model = vframe->get_color_model();
+// do not use shm here, puts too much pressure on 32bit systems
+                               VFrame *cache_frame = new VFrame(vw, vh, vcolor_model, 0);
+                               ret = convert_cmodel(cache_frame, frame);
+                               if( ret > 0 )
+                                       ffmpeg->put_cache_frame(cache_frame, curr_pos);
+                       }
+                       ++curr_pos;
+               }
        }
+       seeking = 0;
        if( frame->format == AV_PIX_FMT_NONE || frame->width <= 0 || frame->height <= 0 )
                ret = -1;
        if( ret >= 0 ) {
@@ -2217,6 +2245,21 @@ int FFMPEG::scan_options(const char *options, AVDictionary *&opts, AVStream *st)
        return ret;
 }
 
+void FFMPEG::put_cache_frame(VFrame *frame, int64_t position)
+{
+       file_base->file->put_cache_frame(frame, position, 0);
+}
+
+int FFMPEG::get_use_cache()
+{
+       return file_base->file->get_use_cache();
+}
+
+void FFMPEG::purge_cache()
+{
+       file_base->file->purge_cache();
+}
+
 FFCodecRemap::FFCodecRemap()
 {
        old_codec = 0;
@@ -3961,6 +4004,9 @@ double FFMPEG::get_initial_timecode(int data_type, int channel, double frame_rat
                fidx = aud->fidx;
                nudge = aud->nudge;
                st = aud->st;
+               AVDictionaryEntry *tref = av_dict_get(fmt_ctx->metadata, "time_reference", 0, 0);
+               if( tref && aud && aud->sample_rate )
+                       return strtod(tref->value, 0) / aud->sample_rate;
                break; }
        case TRACK_VIDEO: {
                codec_type = AVMEDIA_TYPE_VIDEO;
index 1a514e1d57f8f58a4a3124dc411f0e2d408df065..2e1f201f328a38b2dc06dcde889df283ce8922ca 100644 (file)
@@ -138,7 +138,7 @@ public:
        int64_t seek_pos, curr_pos;
        int fidx;
        int reading, writing;
-       int seeked, eof;
+       int seeking, seeked, eof;
 
        int hw_pixfmt;
        AVBufferRef *hw_device_ctx;
@@ -368,6 +368,10 @@ public:
        static double to_secs(int64_t time, AVRational time_base);
        int info(char *text, int len);
 
+       void put_cache_frame(VFrame *frame, int64_t position);
+       int get_use_cache();
+       void purge_cache();
+
        int init_decoder(const char *filename);
        int open_decoder();
        int init_encoder(const char *filename);
index f9571c9d1dddd60bb37704dda5a18d0e740c8200..9828d6ec327527251fc5ef79bac7285bf3f34ddb 100644 (file)
@@ -344,6 +344,24 @@ int File::delete_oldest()
        return frame_cache->delete_oldest();
 }
 
+int File::get_cache_frame(VFrame *frame, int64_t position)
+{
+       return frame_cache->get_cache_frame(frame, position,
+               current_layer, asset->frame_rate);
+}
+
+void File::put_cache_frame(VFrame *frame, int64_t position, int use_copy)
+{
+       frame_cache->put_cache_frame(frame,
+               position, current_layer, asset->frame_rate, use_copy);
+}
+
+int File::get_use_cache()
+{
+       return use_cache;
+}
+
+
 // file driver in order of probe precidence
 //  can be reordered in preferences->interface
 const char *File::default_probes[] = { 
@@ -1149,52 +1167,52 @@ int File::read_frame(VFrame *frame, int is_thread)
        if( debug ) PRINT_TRACE
        int result = 0;
        int supported_colormodel = colormodel_supported(frame->get_color_model());
-       int advance_position = 1;
-       int cache_active = use_cache || asset->single_frame ? 1 : 0;
+       int do_read = 1;
+// if reverse playback reading, use_cache is -1
+       int cache_active = asset->single_frame ? 1 : use_cache;
        int64_t cache_position = !asset->single_frame ? current_frame : -1;
 
 // Test cache
-       if( cache_active && frame_cache->get_frame(frame, cache_position,
-                       current_layer, asset->frame_rate) ) {
-// Can't advance position if cache used.
-//printf("File::read_frame %d\n", __LINE__);
-               advance_position = 0;
+       if( cache_active ) {
+               if( get_cache_frame(frame, cache_position) ) {
+                       do_read = 0;
+               }
+               else if( cache_active < 0 && frame_cache->cache_items() > 0 ) {
+// reverse reading and cache miss, clear cache for new readahead
+                       purge_cache();
+               }
        }
-// Need temp
-       else if( frame->get_color_model() != BC_COMPRESSED &&
-               (supported_colormodel != frame->get_color_model() ||
-               (!file->can_scale_input() &&
-                       (frame->get_w() != asset->width ||
-                        frame->get_h() != asset->height))) ) {
-
-//                     printf("File::read_frame %d\n", __LINE__);
-// Can't advance position here because it needs to be added to cache
-               if( temp_frame ) {
-                       if( !temp_frame->params_match(asset->width, asset->height, supported_colormodel) ) {
-                               delete temp_frame;
-                               temp_frame = 0;
+// Need to read
+       if( do_read ) {
+               VFrame *vframe = frame;
+               if( frame->get_color_model() != BC_COMPRESSED &&
+                   (supported_colormodel != frame->get_color_model() ||
+                       (!file->can_scale_input() &&
+                               (frame->get_w() != asset->width ||
+                                frame->get_h() != asset->height))) ) {
+                       if( temp_frame ) {
+                               if( !temp_frame->params_match(asset->width, asset->height,
+                                               supported_colormodel) ) {
+                                       delete temp_frame;  temp_frame = 0;
+                               }
+                       }
+                       if( !temp_frame ) {
+                               temp_frame = new VFrame(asset->width, asset->height,
+                                               supported_colormodel, 0);
+                               temp_frame->clear_frame();
                        }
-               }
 
-               if( !temp_frame ) {
-                       temp_frame = new VFrame(asset->width, asset->height, supported_colormodel, 0);
-                       temp_frame->clear_frame();
+                       temp_frame->copy_stacks(frame);
+                       vframe = temp_frame;
                }
-
-//                     printf("File::read_frame %d\n", __LINE__);
-               temp_frame->copy_stacks(frame);
-               result = file->read_frame(temp_frame);
-               if( !result )
-                       frame->transfer_from(temp_frame);
-               else if( result && frame->get_status() > 0 )
-                       frame->set_status(-1);
-//printf("File::read_frame %d\n", __LINE__);
-       }
-       else {
-// Can't advance position here because it needs to be added to cache
-//printf("File::read_frame %d\n", __LINE__);
-               result = file->read_frame(frame);
-               if( result && frame->get_status() > 0 )
+               result = file->read_frame(vframe);
+               if( !result ) {
+                       if( frame != vframe )
+                               frame->transfer_from(vframe);
+                       if( cache_active > 0 )
+                               put_cache_frame(frame, cache_position, 1);
+               }
+               else if( frame->get_status() > 0 )
                        frame->set_status(-1);
 //for( int i = 0; i < 100 * 1000; i++ ) ((float*)frame->get_rows()[0])[i] = 1.0;
        }
@@ -1202,12 +1220,9 @@ int File::read_frame(VFrame *frame, int is_thread)
        if( result && !current_frame )
                frame->clear_frame();
 
-       if( cache_active && advance_position && frame->get_status() > 0 )
-               frame_cache->put_frame(frame, cache_position,
-                       current_layer, asset->frame_rate, 1, 0);
 //printf("File::read_frame %d\n", __LINE__);
 
-       if( advance_position ) current_frame++;
+       if( do_read ) current_frame++;
        if( debug ) PRINT_TRACE
        return 0;
 }
index c86a1b4f72b1d9b8911798d1b297779de665ab7d..d09ca7eff08c410f0a43c32d3e948d90d422413e 100644 (file)
@@ -45,7 +45,6 @@
 #include "preferences.inc"
 #include "samples.inc"
 #include "vframe.inc"
-#include "packagingengine.h"
 
 // ======================================= include file types here
 
@@ -56,7 +55,7 @@ class File
 {
 public:
        File();
-       ~File();
+       virtual ~File();
 
        int probe();
 // Get attributes for various file formats.
@@ -238,6 +237,10 @@ public:
 // Used by read_frame.
        int colormodel_supported(int colormodel);
 
+       int get_cache_frame(VFrame *vframe, int64_t position);
+       void put_cache_frame(VFrame *frame, int64_t position, int use_copy);
+       int get_use_cache();
+
 // stubs for now
        static const char *compressiontostr(const char *codec) { return codec; }
        static const char *strtocompression(const char *string) { return string; }
@@ -266,6 +269,8 @@ public:
        int bytes_per_sample(int bits); // Convert the bit descriptor into a byte count.
 // get record stream file descriptor
        int record_fd();
+// brender update video map
+       virtual int write_frame_done(int64_t position) { return 0; }
 
        Asset *asset;    // Copy of asset since File outlives EDL
        FileBase *file; // virtual class for file type
index 4671fc4aab94032af9ddf77bf1e0693df87a247a..dc73ccc5fcd0fe66ffaf3062a37e76f051801647 100644 (file)
@@ -299,4 +299,3 @@ int64_t FileBase::base_memory_usage()
                history_allocated * history_channels * sizeof(double);
 }
 
-
index 8d9b1ae9f22154bbf976d6eee1128853409bb723..a60b3f3e4e5b678a75a69b0543a91af868c7cee8 100644 (file)
@@ -22,6 +22,7 @@
 #include "asset.h"
 #include "arender.h"
 #include "cache.h"
+#include "edl.h"
 #include "filebase.h"
 #include "file.h"
 #include "fileref.h"
index 7f4d67f2ba869d0ab05881e3e8f28b20c297858e..bfbca7eb4a6e31cbda44fede6493ed2bb3be9aca 100644 (file)
 
 #include "asset.inc"
 #include "cache.inc"
+#include "edl.inc"
 #include "filebase.h"
 #include "file.inc"
+#include "maxchannels.h"
 #include "renderengine.inc"
 #include "samples.inc"
 #include "transportque.inc"
index 84b20fcdd45fbf289833c9c8dd6623143f8b2ba4..8fadbeea9fd45e64835bb66d1fec285d0950b11e 100644 (file)
@@ -277,16 +277,20 @@ void FileThread::run()
                                        else
                                        if(do_video)
                                        {
-                                               if(compressed)
-                                               {
-                                                       for(j = 0; j < file->asset->layers && !result; j++)
-                                                               for(i = 0; i < output_size[local_buffer] && !result; i++)
-                                                                       result = file->write_compressed_frame(video_buffer[local_buffer][j][i]);
+                                               int layers = 1, count = output_size[local_buffer];
+                                               VFrame ***frames = video_buffer[local_buffer];
+                                               if( compressed ) {
+                                                       layers = file->asset->layers;
+                                                       for( j=0; j<layers && !result; ++j )
+                                                               for( i=0; i<count && !result; ++i )
+                                                                       result = file->write_compressed_frame(frames[j][i]);
                                                }
                                                else
-                                               {
-                                                       result = file->write_frames(video_buffer[local_buffer],
-                                                               output_size[local_buffer]);
+                                                       result = file->write_frames(frames, count);
+                                               if( !result ) {
+                                                       for( j=0; j<layers && !result; ++j )
+                                                               for( i=0; i<count && !result; ++i )
+                                                                       file->write_frame_done(frames[j][i]->get_number());
                                                }
                                        }
 
index d575c38e9d846aa2c507145582600c0da821a556..a72d525292122f10b9eccc8b45f7f47928e1bf61 100644 (file)
@@ -34,6 +34,7 @@ FloatAuto::FloatAuto(EDL *edl, FloatAutos *autos)
  : Auto(edl, (Autos*)autos)
 {
        value = 0;
+       value1 = 0;
        control_in_value = 0;
        control_out_value = 0;
        control_in_position = 0;
@@ -68,6 +69,7 @@ int FloatAuto::operator==(FloatAuto &that)
 int FloatAuto::identical(FloatAuto *src)
 {
        return EQUIV(value, src->value) &&
+               (curve_mode != BUMP || EQUIV(value1, src->value1)) &&
                EQUIV(control_in_value, src->control_in_value) &&
                EQUIV(control_out_value, src->control_out_value);
                // ctrl positions ignored, as they may depend on neighbours
@@ -78,6 +80,7 @@ int FloatAuto::identical(FloatAuto *src)
 int FloatAuto::equals(FloatAuto *that)
 {
        return this->value == that->value &&
+               (this->curve_mode != BUMP || this->value1 == that->value1) &&
                this->control_in_value == that->control_in_value &&
                this->control_out_value == that->control_out_value &&
                this->control_in_position == that->control_in_position &&
@@ -86,21 +89,6 @@ int FloatAuto::equals(FloatAuto *that)
 }
 
 
-/* Note: the following is essentially display-code and has been moved to:
- *  TrackCanvas::value_to_percentage(float auto_value, int autogrouptype)
- *
-float FloatAuto::value_to_percentage()
-{
-}
-float FloatAuto::value_to_percentage()
-{
-}
-float FloatAuto::value_to_percentage()
-{
-}
-*/
-
-
 void FloatAuto::copy_from(Auto *that)
 {
        copy_from((FloatAuto*)that);
@@ -110,6 +98,7 @@ void FloatAuto::copy_from(FloatAuto *that)
 {
        Auto::copy_from(that);
        this->value = that->value;
+       this->value1 = that->value1;
        this->control_in_value = that->control_in_value;
        this->control_out_value = that->control_out_value;
        this->control_in_position = that->control_in_position;
@@ -169,33 +158,37 @@ int FloatAuto::interpolate_from(Auto *a1, Auto *a2, int64_t pos, Auto *templ)
 }
 
 
-void FloatAuto::change_curve_mode(t_mode new_mode)
+void FloatAuto::change_curve_mode(t_mode new_mode, int adjust)
 {
        if(new_mode == TFREE && !(control_in_position && control_out_position))
                new_mode = FREE; // only if curves on both sides...
+       else if(new_mode == BUMP )
+               value1 = value;  // continuous
 
        curve_mode = new_mode;
-       adjust_curves();
+       if( adjust )
+               adjust_curves();
 }
 
 void FloatAuto::toggle_curve_mode()
 {
        switch (curve_mode) {
-       case SMOOTH:    change_curve_mode(TFREE);  break;
-       case LINEAR:    change_curve_mode(FREE);   break;
-       case TFREE :    change_curve_mode(LINEAR); break;
-       case FREE  :    change_curve_mode(SMOOTH); break;
+       case SMOOTH:    change_curve_mode(LINEAR);  break;
+       case LINEAR:    change_curve_mode(TFREE);   break;
+       case TFREE :    change_curve_mode(FREE);    break;
+       case FREE  :    change_curve_mode(BUMP);    break;
+       case BUMP  :    change_curve_mode(SMOOTH);  break;
        }
 }
 
-
-void FloatAuto::set_value(float value)
+// edge=0:left edge, 1:right edge, -1:both edges
+void FloatAuto::set_value(float value, int edge)
 {
        float float_min = ((FloatAutos*)autos)->float_min;
-       if( value < float_min ) value = float_min;
        float float_max = ((FloatAutos*)autos)->float_max;
-       if( value > float_max ) value = float_max;
-       this->value = value;
+       bclamp(value, float_min, float_max);
+       if( curve_mode != BUMP || edge <= 0 ) this->value = value;
+       if( curve_mode == BUMP && edge != 0 ) this->value1 = value;
        this->adjust_curves();
        if(previous) ((FloatAuto*)previous)->adjust_curves();
        if(next)     ((FloatAuto*)next)->adjust_curves();
@@ -205,7 +198,8 @@ void FloatAuto::set_control_in_value(float newvalue)
 {
        switch(curve_mode) {
        case TFREE:     control_out_value = control_out_position*newvalue / control_in_position;
-       case FREE:      control_in_value = newvalue;
+       case FREE:
+       case BUMP:      control_in_value = newvalue;
        default:        return; // otherwise calculated automatically...
        }
 }
@@ -214,7 +208,8 @@ void FloatAuto::set_control_out_value(float newvalue)
 {
        switch(curve_mode) {
        case TFREE:     control_in_value = control_in_position*newvalue / control_out_position;
-       case FREE:      control_out_value=newvalue;
+       case FREE:
+       case BUMP:      control_out_value = newvalue;
        default:        return;
        }
 }
@@ -298,7 +293,9 @@ inline void FloatAuto::calculate_slope(FloatAuto *left, FloatAuto *right, float
        if(!left || !right) return;
 
        dx = right->position - left->position;
-       float dv = right->value - left->value;
+       float lval = left->get_value(0);
+       float rval = right->get_value(1);
+       float dv = rval - lval;
        dvdx = (dx == 0) ? 0 : dv/dx;
 }
 
@@ -361,9 +358,8 @@ void FloatAuto::adjust_to_new_coordinates(int64_t position, float value)
 // define new position and value in one step, do necessary re-adjustments
 {
        float float_min = ((FloatAutos*)autos)->float_min;
-       if( value < float_min ) value = float_min;
        float float_max = ((FloatAutos*)autos)->float_max;
-       if( value > float_max ) value = float_max;
+       bclamp(value, float_min, float_max);
        this->value = value;
        this->position = position;
        adjust_ctrl_positions();
@@ -411,6 +407,7 @@ void FloatAuto::copy(int64_t start, int64_t end, FileXML *file, int default_auto
        else
                file->tag.set_property("POSITION", position - start);
        file->tag.set_property("VALUE", value);
+       file->tag.set_property("VALUE1", value1);
        file->tag.set_property("CONTROL_IN_VALUE", control_in_value / 2.0); // compatibility, see below
        file->tag.set_property("CONTROL_OUT_VALUE", control_out_value / 2.0);
        file->tag.set_property("TANGENT_MODE", (int)curve_mode);
@@ -422,11 +419,12 @@ void FloatAuto::copy(int64_t start, int64_t end, FileXML *file, int default_auto
 
 void FloatAuto::load(FileXML *file)
 {
-       value = file->tag.get_property("VALUE", value);
        float float_min = ((FloatAutos*)autos)->float_min;
-       if( value < float_min ) value = float_min;
        float float_max = ((FloatAutos*)autos)->float_max;
-       if( value > float_max ) value = float_max;
+       value = file->tag.get_property("VALUE", value);
+       bclamp(value, float_min, float_max);
+       value1 = file->tag.get_property("VALUE1", value1);
+       bclamp(value, float_min, float_max);
        control_in_value = file->tag.get_property("CONTROL_IN_VALUE", control_in_value);
        control_out_value = file->tag.get_property("CONTROL_OUT_VALUE", control_out_value);
        curve_mode = (t_mode)file->tag.get_property("TANGENT_MODE", (int)FREE);
@@ -448,8 +446,40 @@ const char *FloatAuto::curve_name(int curve_mode)
        case FloatAuto::SMOOTH: return _("Smooth");
        case FloatAuto::LINEAR: return _("Linear");
        case FloatAuto::TFREE:  return _("Tangent");
-               case FloatAuto::FREE:   return _("Disjoint");
-        }
-        return _("Error");
+       case FloatAuto::FREE:   return _("Disjoint");
+       case FloatAuto::BUMP:   return _("Bump");
+       }
+       return _("Error");
+}
+
+void FloatAuto::bump_update(int64_t pos, float dv, int edge, int span)
+{
+       float *mins = autos->edl->local_session->automation_mins;
+       float *maxs = autos->edl->local_session->automation_maxs;
+       int group = autos->autogrouptype;
+       float min = mins[group], max = maxs[group];
+       int last_edge = edge;
+       FloatAuto *fauto = this;
+       fauto->position = pos;
+       if( fauto->is_bump() && span ) {
+               do {
+                       float v = fauto->get_value(edge) + dv;
+                       bclamp(v, min, max);
+                       fauto->set_value(v, edge);
+                       fauto = (FloatAuto*)(!edge ? fauto->next : fauto->previous);
+               } while( fauto && !fauto->is_bump() );
+               last_edge = !edge ? 1 : 0;
+       }
+       if( fauto ) {
+               float v = fauto->get_value(last_edge) + dv;
+               bclamp(v, min, max);
+               fauto->set_value(v, last_edge);
+       }
+}
+
+void FloatAuto::bump_value(float v, int edge, int span)
+{
+       float dv = v - get_value(edge);
+       bump_update(position, dv, edge, span);
 }
 
index cc4168c46c824b60f526a136459d1742f155b1bc..a6b9c192403fea436f79a7609e09c65554bc4e31 100644 (file)
@@ -49,9 +49,14 @@ public:
        void copy(int64_t start, int64_t end, FileXML *file, int default_only);
        void load(FileXML *xml);
 
-// "the value" (=payload of this keyframe)
-       float get_value() {return this->value;}
-       void  set_value(float newval);
+// for curves, edge==0: the right value, for bumps, edge!=0: the left value1
+       float get_value(int edge=0) {
+               return curve_mode==BUMP && edge ? this->value1 : this->value;
+       }
+// edge==0: set value, for bumps: edge>0, set value1, edge<0: set both
+       void set_value(float value, int edge=-1);
+       void bump_update(int64_t pos, float dv, int edge, int span);
+       void bump_value(float v, int edge, int span);
 
 // Possible policies to handle the tagents for the
 // bézier curves connecting adjacent automation points
@@ -60,12 +65,14 @@ public:
                SMOOTH,     // curves are coupled in order to yield a smooth curve
                LINEAR,     // curves always pointing directly to neighbouring automation points
                TFREE,      // curves on both sides coupled but editable by dragging the handles
-               FREE        // curves on both sides are independent and editable via GUI
+               FREE,       // curves on both sides are independent and editable via GUI
+               BUMP,       // curves and values both sides are independent and editable via GUI
        };
 
        t_mode curve_mode;
-       void change_curve_mode(t_mode); // recalculates curves as well
+       void change_curve_mode(t_mode, int adjust=1); // recalculates curves as well
        void toggle_curve_mode();       // cycles through all modes (e.g. by ctrl-click)
+       int is_bump() { return curve_mode == BUMP ? 1 : 0; }
 
 // Control values (y coords of bézier control point), relative to value
        float get_control_in_value()            {check_pos(); return this->control_in_value;}
@@ -82,7 +89,6 @@ public:
        void adjust_to_new_coordinates(int64_t position, float value);
 // text name for curve mode
        static const char *curve_name(int curve_mode);
-
 private:
        void adjust_curves();             // recalc. ctrk in and out points, if automatic curve mode (SMOOTH or LINEAR)
        void adjust_ctrl_positions(FloatAuto *p=0, FloatAuto *n=0); // recalc. x location of ctrl points, notify neighbours
@@ -93,7 +99,7 @@ private:
        void handle_automatic_curve_after_copy();
 
 // Control values are relative to value
-       float value, control_in_value, control_out_value;
+       float value, control_in_value, control_out_value, value1;
 // X control positions relative to value position for drawing.
 // In native units of the track.
        int64_t control_in_position, control_out_position;
index ca8dc6bf2f95e42f31d101ffb85b7b654daa1cd4..bebbbcc1559e27c4d59d7fed5fd376355f909aa2 100644 (file)
@@ -235,48 +235,58 @@ float FloatAutos::get_value(int64_t position,
        next = (FloatAuto*)get_next_auto(position, direction, (Auto* &)next, 0);
 
 // Constant
-       if(!next && !previous) return ((FloatAuto*)default_auto)->get_value();
-       if(!previous) return next->get_value();
-       if(!next) return previous->get_value();
-       if(next == previous) return previous->get_value();
-
-       if(direction == PLAY_FORWARD)
-       {
-               if(EQUIV(previous->get_value(), next->get_value())) {
+       if( !next && !previous )
+               return ((FloatAuto*)default_auto)->get_value();
+       if( next == previous )
+               return previous->get_value();
+
+       if( direction == PLAY_FORWARD) {
+               if( !previous ) return next->get_value(1);
+               if( !next ) return previous->get_value(0);
+               if( EQUIV(previous->get_value(0), next->get_value(1)) ) {
                        if( (previous->curve_mode == FloatAuto::LINEAR &&
                             next->curve_mode == FloatAuto::LINEAR) ||
                            (EQUIV(previous->get_control_out_value(), 0) &&
-                            EQUIV(next->get_control_in_value(), 0))) {
-                               return previous->get_value();
+                            EQUIV(next->get_control_in_value(), 0)) ) {
+                               return previous->get_value(0);
                        }
                }
        }
        else if(direction == PLAY_REVERSE) {
-               if(EQUIV(previous->get_value(), next->get_value())) {
+               if( !previous ) return next->get_value(0);
+               if( !next ) return previous->get_value(1);
+               if( EQUIV(previous->get_value(0), next->get_value(1)) ) {
                        if( (previous->curve_mode == FloatAuto::LINEAR &&
                             next->curve_mode == FloatAuto::LINEAR) ||
                            (EQUIV(previous->get_control_in_value(), 0) &&
-                            EQUIV(next->get_control_out_value(), 0))) {
-                               return previous->get_value();
+                            EQUIV(next->get_control_out_value(), 0)) ) {
+                               return previous->get_value(1);
                        }
                }
        }
 // at this point: previous and next not NULL, positions differ, value not constant.
 
-       return calculate_bezier(previous, next, position);
+       return calculate_bezier(previous, next, position, direction);
 }
 
 
-float FloatAutos::calculate_bezier(FloatAuto *previous, FloatAuto *next, int64_t position)
+float FloatAutos::calculate_bezier(FloatAuto *previous, FloatAuto *next,
+               int64_t position, int direction)
 {
-       if(next->position - previous->position == 0) return previous->get_value();
+       int edge = direction == PLAY_FORWARD ? 0 : 1;
+       if( next->position == previous->position )
+               return previous->get_value(edge);
 
-       float y0 = previous->get_value();
-       float y3 = next->get_value();
+       float y0 = previous->get_value(edge);
+       float y3 = next->get_value(1-edge);
 
 // control points
-       float y1 = previous->get_value() + previous->get_control_out_value();
-       float y2 = next->get_value() + next->get_control_in_value();
+       float y1 = y0 + (direction == PLAY_FORWARD ?
+               previous->get_control_out_value() :
+               previous->get_control_in_value());
+       float y2 = y3 + (direction == PLAY_FORWARD ?
+               next->get_control_in_value() :
+               next->get_control_out_value());
        float t = (float)(position - previous->position) /
                        (next->position - previous->position);
 
@@ -306,12 +316,12 @@ float FloatAutos::calculate_bezier_derivation(FloatAuto *previous, FloatAuto *ne
                        return 0;
                return previous->get_control_out_value() / previous->get_control_out_position();
        }
-       float y0 = previous->get_value();
-       float y3 = next->get_value();
+       float y0 = previous->get_value(0);
+       float y3 = next->get_value(1);
 
 // control points
-       float y1 = previous->get_value() + previous->get_control_out_value();
-       float y2 = next->get_value() + next->get_control_in_value();
+       float y1 = y0 + previous->get_control_out_value();
+       float y2 = y3 + next->get_control_in_value();
 // normalized scale
        float t = (float)(position - previous->position) / scale;
 
@@ -416,10 +426,14 @@ void FloatAutos::set_proxy(int orig_scale, int new_scale)
        float orig_value;
        orig_value = ((FloatAuto*)default_auto)->value * orig_scale;
        ((FloatAuto*)default_auto)->value = orig_value / new_scale;
+       orig_value = ((FloatAuto*)default_auto)->value1 * orig_scale;
+       ((FloatAuto*)default_auto)->value1 = orig_value / new_scale;
 
        for( FloatAuto *current= (FloatAuto*)first; current; current=(FloatAuto*)NEXT ) {
                orig_value = current->value * orig_scale;
                current->value = orig_value / new_scale;
+               orig_value = current->value1 * orig_scale;
+               current->value1 = orig_value / new_scale;
                orig_value = current->control_in_value * orig_scale;
                current->control_in_value = orig_value / new_scale;
                orig_value = current->control_out_value * orig_scale;
@@ -460,17 +474,16 @@ double FloatAutos::automation_integral(int64_t start, int64_t length, int direct
                if( prev ) prev_pos = prev->position;
                FloatAuto *next = (FloatAuto*)get_next_auto(pos, direction, znext, 0);
                if( next ) next_pos = next->position;
-               if( !prev && !next ) prev = next = (FloatAuto*)default_auto;
-               else if( !prev ) prev = next;
-               else if( !next ) next = prev;
-
+               if( !prev && !next ) prev = (FloatAuto*)default_auto;
                double dt = next_pos - prev_pos;
                double t0 = (pos - prev_pos) / dt;
                if( (pos = next_pos) > end ) pos = end;
                double t1 = (pos - prev_pos) / dt;
 
-               double y0 = prev->get_value(), y1 = y0 + prev->get_control_out_value();
-               double y3 = next->get_value(), y2 = y3 + next->get_control_in_value();
+               double y0 = !prev ? next->get_value(1) : prev->get_value(0);
+               double y1 = y0 + (!prev ? 0 : prev->get_control_out_value());
+               double y3 = !next ? prev->get_value(0) : next->get_value(1);
+               double y2 = y3 + (!next ? 0 : next->get_control_in_value());
                if( y0 != y1 || y1 != y2 || y2 != y3 ) {
 // bezier definite integral t0..t1
                        double f4 = -y0/4 + 3*y1/4 - 3*y2/4 + y3/4;
index f53564d4052d0b0c9d3c4944bc98e48b3919341c..6842d54e71d026986125aff392c78dbe268e99ea 100644 (file)
@@ -27,6 +27,7 @@
 #include "guicast.h"
 #include "filexml.inc"
 #include "floatauto.inc"
+#include "transportque.inc"
 
 class FloatAutos : public Autos
 {
@@ -38,29 +39,25 @@ public:
        ~FloatAutos();
 
 
-       void draw_joining_line(BC_SubWindow *canvas, int vertical, int center_pixel, int x1, int y1, int x2, int y2);
+       void draw_joining_line(BC_SubWindow *canvas, int vertical, int center_pixel,
+                       int x1, int y1, int x2, int y2);
        int get_testy(float slope, int cursor_x, int ax, int ay);
 // Return 1 if the automation is constant.
 // constant - set to the value if it is constant
-       int automation_is_constant(int64_t start,
-               int64_t length,
-               int direction,
-               double &constant);
+       int automation_is_constant(int64_t start, int64_t length, int direction,
+                       double &constant);
        double get_automation_constant(int64_t start, int64_t end);
 // Get value at a specific point.  This needs previous and next stores
 // because it is used for every pixel in the timeline drawing function.
-       float get_value(int64_t position,
-               int direction,
-               FloatAuto* &previous,
-               FloatAuto* &next);
+       float get_value(int64_t position, int direction,
+                       FloatAuto* &previous, FloatAuto* &next);
 // Helper: just calc the bezier function without doing any lookup of nodes
-       static float calculate_bezier(FloatAuto *previous, FloatAuto *next, int64_t position);
-       static float calculate_bezier_derivation(FloatAuto *previous, FloatAuto *next, int64_t position);
-       void get_extents(float *min,
-               float *max,
-               int *coords_undefined,
-               int64_t unit_start,
-               int64_t unit_end);
+       static float calculate_bezier(FloatAuto *previous, FloatAuto *next,
+                       int64_t position, int direction=PLAY_FORWARD);
+       static float calculate_bezier_derivation(FloatAuto *previous, FloatAuto *next,
+                       int64_t position);
+       void get_extents(float *min, float *max, int *coords_undefined,
+                       int64_t unit_start, int64_t unit_end);
 
        void set_automation_mode(int64_t start, int64_t end, int mode);
        void set_proxy(int orig_scale, int new_scale);
index f78a45bd1e092a990864e9efd716a88cd430d954..7f52fe0c8e4c1a5f5d4e886fd8ab30dc3afe32fa 100644 (file)
@@ -429,9 +429,11 @@ int CrossfadeFFT::process_buffer(int64_t output_sample,
        }
 
        input_buffer->set_offset(input_size);
-       result = read_samples(input_sample, need_samples-input_size, input_buffer);
+       if( need_samples > input_size ) {
+               result = read_samples(input_sample, need_samples-input_size, input_buffer);
+               input_sample += step * (need_samples - input_size);
+       }
        input_buffer->set_offset(0);
-       input_sample += step * (need_samples - input_size);
        input_size = need_samples;
 
 
index fdf7ef358e11088c696869555efefbe5d354469c..b8eed886c4435d3810a66af33d226c9d21994ac5 100644 (file)
@@ -79,212 +79,156 @@ FrameCache::~FrameCache()
 }
 
 
-// Returns 1 if frame exists in cache and copies it to the frame argument.
-int FrameCache::get_frame(VFrame *frame,
-       int64_t position,
-       int layer,
-       double frame_rate,
-       int source_id)
-{
-       lock->lock("FrameCache::get_frame");
-       FrameCacheItem *result = 0;
-
-       if(frame_exists(frame,
-               position,
-               layer,
-               frame_rate,
-               &result,
-               source_id))
-       {
-               if(result->data)
-               {
-// Frame may have come from the readahead thread.
-// Those frames are in the codec color model.
-// But to pass frame_exists, they must be identical.
-//                     BC_CModels::transfer(frame->get_rows(),
-//                             result->data->get_rows(),
-//                             result->data->get_y(),
-//                             result->data->get_u(),
-//                             result->data->get_v(),
-//                             frame->get_y(),
-//                             frame->get_u(),
-//                             frame->get_v(),
-//                             0,
-//                             0,
-//                             result->data->get_w(),
-//                             result->data->get_h(),
-//                             0,
-//                             0,
-//                             frame->get_w(),
-//                             frame->get_h(),
-//                             result->data->get_color_model(),
-//                             frame->get_color_model(),
-//                             0,
-//                             result->data->get_w(),
-//                             frame->get_w());
-
-// no context data since keyframe updates may vary input
-                       frame->copy_from(result->data);
-               }
-               result->age = get_age();
-       }
-
-
-
-
-       lock->unlock();
-       if(result) return 1;
-       return 0;
-}
-
-
-VFrame* FrameCache::get_frame_ptr(int64_t position,
-       int layer,
-       double frame_rate,
-       int color_model,
-       int w,
-       int h,
-       int source_id)
+VFrame* FrameCache::get_frame_ptr(int64_t position, int layer, double frame_rate,
+               int color_model, int w, int h, int source_id)
 {
        lock->lock("FrameCache::get_frame_ptr");
-       FrameCacheItem *result = 0;
-       if(frame_exists(position,
-               layer,
-               frame_rate,
-               color_model,
-               w,
-               h,
-               &result,
-               source_id))
-       {
-               result->age = get_age();
-               return result->data;
-       }
-
-
+       VFrame *vframe = get_vframe(position, w, h, color_model,
+                       layer, frame_rate, source_id);
+       if( vframe ) return vframe;  // not unlocked
        lock->unlock();
        return 0;
 }
 
-// Puts frame in cache if enough space exists and the frame doesn't already
-// exist.
-void FrameCache::put_frame(VFrame *frame, int64_t position,
-       int layer, double frame_rate, int use_copy, Indexable *indexable)
+VFrame *FrameCache::get_vframe(int64_t position, int w, int h,
+               int color_model, int layer, double frame_rate,
+               int source_id)
 {
-       lock->lock("FrameCache::put_frame");
        FrameCacheItem *item = 0;
-       int source_id = -1;
-       if(indexable) source_id = indexable->id;
-
-//printf("FrameCache::put_frame %d position=%jd\n", __LINE__, position);
-
-       if(frame_exists(frame, position, layer, frame_rate, &item, source_id)) {
+       int ret = frame_exists(position, layer, frame_rate,
+                       w, h, color_model, &item, source_id);
+       if( ret && position >= 0 && item )
                item->age = get_age();
-               lock->unlock();
-               return;
-       }
+       return ret && item ? item->data : 0;
+}
 
+VFrame *FrameCache::get_frame(int64_t position, int w, int h,
+               int color_model, int layer, double frame_rate,
+               int source_id)
+{
+       lock->lock("FrameCache::get_frame");
+       VFrame *frame = get_vframe(position, w, h,
+                       color_model, layer, frame_rate, source_id);
+       lock->unlock();
+       return frame;
+}
 
-       item = new FrameCacheItem;
+// Returns 1 if frame exists in cache and copies it to the frame argument.
+int FrameCache::get_frame(VFrame *frame, int64_t position,
+               int layer, double frame_rate, int source_id)
+{
+       lock->lock("FrameCache::get_frame");
+       VFrame *vframe = get_vframe(position,
+                       frame->get_w(), frame->get_h(), frame->get_color_model(),
+                       layer, frame_rate, source_id);
+       if( vframe )
+               frame->copy_from(vframe);
+       lock->unlock();
+       return vframe ? 1 : 0;
+}
 
-       item->data = use_copy ? new VFrame(*frame) : frame;
 
-// Copy metadata
+void FrameCache::put_vframe(VFrame *frame, int64_t position,
+               int layer, double frame_rate, int source_id)
+{
+       FrameCacheItem *item = new FrameCacheItem;
+       item->data = frame;
        item->position = position;
        item->layer = layer;
        item->frame_rate = frame_rate;
        item->source_id = source_id;
-       if(indexable)
-               item->path = cstrdup(indexable->path);
-
        item->age = position < 0 ? INT_MAX : get_age();
-
-//printf("FrameCache::put_frame %d position=%jd\n", __LINE__, position);
        put_item(item);
+}
+
+// Puts frame in cache if the frame doesn't already exist.
+void FrameCache::put_frame(VFrame *frame, int64_t position,
+               int layer, double frame_rate, int use_copy, Indexable *idxbl)
+{
+       int source_id = idxbl ? idxbl->id : -1;
+       lock->lock("FrameCache::put_frame");
+       VFrame *vframe = get_vframe(position,
+                       frame->get_w(), frame->get_h(), frame->get_color_model(),
+                       layer, frame_rate, source_id);
+       if( !vframe ) {
+               if( use_copy ) frame = new VFrame(*frame);
+               put_vframe(frame, position, layer, frame_rate, source_id);
+       }
        lock->unlock();
 }
 
+// get vframe for keys, overwrite frame if found
+int FrameCache::get_cache_frame(VFrame *frame, int64_t position,
+               int layer, double frame_rate)
+{
+       lock->lock("FrameCache::get_cache_frame");
+       VFrame *vframe = get_vframe(position,
+               frame->get_w(), frame->get_h(), frame->get_color_model(),
+               layer, frame_rate, -1);
+       if( vframe )
+               frame->copy_from(vframe);
+       lock->unlock();
+       return vframe ? 1 : 0;
+}
 
+// adds or replaces vframe, consumes frame if not use_copy
+void FrameCache::put_cache_frame(VFrame *frame, int64_t position,
+               int layer, double frame_rate, int use_copy)
+{
+       lock->lock("FrameCache::put_cache_frame");
+       FrameCacheItem *item = 0;
+       int w = frame->get_w(), h = frame->get_h(); 
+       int color_model = frame->get_color_model();
+       int ret = frame_exists(position, layer, frame_rate,
+                       w, h, color_model, &item, -1);
+       if( use_copy ) {
+// do not use shm here, puts too much pressure on 32bit systems
+               VFrame *vframe = new VFrame(w, h, color_model, 0);
+               vframe->copy_from(frame);
+               frame = vframe;
+       }
+       if( ret ) {
+               delete item->data;
+               item->data = frame;
+       }
+       else
+               put_vframe(frame, position, layer, frame_rate, -1);
+       lock->unlock();
+}
 
 
 int FrameCache::frame_exists(VFrame *format, int64_t position,
        int layer, double frame_rate, FrameCacheItem **item_return, int source_id)
 {
        FrameCacheItem *item = (FrameCacheItem*)get_item(position);
-// printf("FrameCache::frame_exists %d item=%p item->position=%jd position=%jd\n",
-// __LINE__,
-// item,
-// item ? item->position : 0,
-// position);
-
-       while(item && item->position == position)
-       {
-// printf("FrameCache::frame_exists %d %f,%f %d,%d %d,%d format match=%d item->data=%p\n",
-// __LINE__,
-// item->frame_rate,
-// frame_rate,
-// item->layer,
-// layer,
-// item->source_id,
-// source_id,
-// format->equivalent(item->data, 1),
-// item->data);
-// format->dump_params();
-
-// This originally tested the frame stacks because a change in the
-// interpolate plugin could cause CR2 to interpolate or not interpolate.
-// This was disabled.
-               if(EQUIV(item->frame_rate, frame_rate) &&
-                       layer == item->layer &&
-                       format->equivalent(item->data, 0) &&
-                       (source_id == -1 || item->source_id == -1 || source_id == item->source_id))
-               {
+       for( ; item && item->position == position; item = (FrameCacheItem*)item->next ) {
+               if( !EQUIV(item->frame_rate, frame_rate) ) continue;
+               if( layer != item->layer ) continue;
+               if( !format->equivalent(item->data, 0) ) continue;
+               if( source_id == -1 || item->source_id == -1 ||
+                   source_id == item->source_id ) {
                        *item_return = item;
                        return 1;
                }
-               else
-                       item = (FrameCacheItem*)item->next;
        }
        return 0;
 }
 
-int FrameCache::frame_exists(int64_t position,
-       int layer,
-       double frame_rate,
-       int color_model,
-       int w,
-       int h,
-       FrameCacheItem **item_return,
-       int source_id)
+int FrameCache::frame_exists(int64_t position, int layer, double frame_rate,
+               int w, int h, int color_model, FrameCacheItem **item_return, int source_id)
 {
        FrameCacheItem *item = (FrameCacheItem*)get_item(position);
-       while(item && item->position == position)
-       {
-// printf("FrameCache::frame_exists %d %f,%f %d,%d %d,%d %d,%d\n",
-// __LINE__,
-// item->frame_rate,
-// frame_rate,
-// item->layer,
-// layer,
-// item->data->get_color_model(),
-// color_model,
-// item->data->get_w(),
-// w,
-// item->data->get_h(),
-// h);
-
-               if(EQUIV(item->frame_rate, frame_rate) &&
-                       layer == item->layer &&
-                       color_model == item->data->get_color_model() &&
-                       w == item->data->get_w() &&
-                       h == item->data->get_h() &&
-                       (source_id == -1 || item->source_id == -1 || source_id == item->source_id))
-               {
+       for( ; item && item->position == position ; item = (FrameCacheItem*)item->next ) {
+               if( !EQUIV(item->frame_rate, frame_rate) ) continue;
+               if( layer != item->layer ) continue;
+               if( color_model != item->data->get_color_model() ) continue;
+               if( w != item->data->get_w() ) continue;
+               if( h != item->data->get_h() ) continue;
+               if( source_id == -1 || item->source_id == -1 ||
+                   source_id == item->source_id ) {
                        *item_return = item;
                        return 1;
                }
-               else
-                       item = (FrameCacheItem*)item->next;
        }
        return 0;
 }
index 54222ff72ba7e3eb7472d79e03e6799e9a51cde4..5708e006c4565eb2566d25c52e6be8810bf4146c 100644 (file)
@@ -57,60 +57,49 @@ public:
        FrameCache();
        ~FrameCache();
 
-// Returns 1 if frame exists in cache and copies it to the frame argument.
-       int get_frame(VFrame *frame,
-               int64_t position,
-               int layer,
-               double frame_rate,
-               int source_id = -1);
 // Returns pointer to cache entry if frame exists or 0.
 // If a frame is found, the frame cache is left in the locked state until
 // unlock is called.  If nothing is found, the frame cache is unlocked before
 // returning.  This keeps the item from being deleted.
 // asset - supplied by user if the cache is not part of a file.
-       VFrame* get_frame_ptr(int64_t position,
-               int layer,
-               double frame_rate,
-               int color_model,
-               int w,
-               int h,
-               int source_id = -1);
+       VFrame* get_frame_ptr(int64_t position, int layer, double frame_rate,
+                       int color_model, int w, int h, int source_id);
+// lock and call get_vframe
+       VFrame *get_vframe(int64_t position, int w, int h,
+                       int color_model, int layer, double frame_rate,
+                       int source_id);
+// caller holds lock
+       VFrame *get_frame(int64_t position, int w, int h,
+                       int color_model, int layer, double frame_rate,
+                       int source_id);
+// Returns 1 if frame exists in cache and copies it to the frame argument.
+       int get_frame(VFrame *frame, int64_t position,
+                       int layer, double frame_rate, int source_id);
 // Puts the frame in cache.
 // use_copy - if 1 a copy of the frame is made.  if 0 the argument is stored.
 // The copy of the frame is deleted by FrameCache in a future delete_oldest.
 // asset - supplied by user if the cache is not part of a file.
-       void put_frame(VFrame *frame,
-               int64_t position,
-               int layer,
-               double frame_rate,
-               int use_copy,
-               Indexable *indexable);
-
+// caller holds lock
+       void put_vframe(VFrame *frame, int64_t position,
+                       int layer, double frame_rate, int source_id);
+// lock, call get_vframe, if exists: ret = 0; else add frame, ret = 1; unlock
+       void put_frame(VFrame *frame, int64_t position,
+                       int layer, double frame_rate, int use_copy, Indexable *idxbl);
+       int get_cache_frame(VFrame *frame, int64_t position,
+                       int layer, double frame_rate);
+       void put_cache_frame(VFrame *frame, int64_t position,
+                       int layer, double frame_rate, int use_copy);
        void dump();
 
-
-
-
-
 private:
 // Return 1 if matching frame exists.
 // Return 0 if not.
        int frame_exists(VFrame *format,
-               int64_t position,
-               int layer,
-               double frame_rate,
-               FrameCacheItem **item_return,
-               int source_id);
-       int frame_exists(int64_t position,
-               int layer,
-               double frame_rate,
-               int color_model,
-               int w,
-               int h,
-               FrameCacheItem **item_return,
-               int source_id);
+                       int64_t position, int layer, double frame_rate,
+                       FrameCacheItem **item_return, int source_id);
+       int frame_exists(int64_t position, int layer, double frame_rate,
+                       int w, int h, int color_model,
+                       FrameCacheItem **item_return, int source_id);
 };
 
-
-
 #endif
index bc250716b68b3937500159f6c779b21a0499d037..1fac6105e59ed24c8038f1b258fe872b28880104 100644 (file)
@@ -294,7 +294,7 @@ void GWindowGUI::create_objects()
                                hard_edges = toggle;
                                break;
                        }
-                        if( accel ) {
+                       if( accel ) {
                                int x1 = get_w() - BC_Title::calculate_w(this, accel) - xs10;
                                add_subwindow(new BC_Title(x1, y, accel));
                        }
index 7457773a08f51a7c4c38ba79ced81bf969a532bf..c3dcaea1c73024d3f0ee7980e749f1ec78cb8187 100644 (file)
@@ -67,6 +67,7 @@ KeyframePopup::KeyframePopup(MWindow *mwindow, MWindowGUI *gui)
        key_mbar = 0;
        key_mode_displayed = false;
        key_edit_displayed = false;
+       popx = popy = 0;
 }
 
 KeyframePopup::~KeyframePopup()
@@ -77,6 +78,7 @@ KeyframePopup::~KeyframePopup()
                delete key_linear;
                delete key_free_t;
                delete key_free;
+               delete key_bump;
        }
        if( !key_edit_displayed ) {
                delete key_edit;
@@ -96,10 +98,12 @@ void KeyframePopup::create_objects()
        key_linear = new KeyframePopupCurveMode(mwindow, this, FloatAuto::LINEAR);
        key_free_t = new KeyframePopupCurveMode(mwindow, this, FloatAuto::TFREE );
        key_free   = new KeyframePopupCurveMode(mwindow, this, FloatAuto::FREE  );
+       key_bump   = new KeyframePopupCurveMode(mwindow, this, FloatAuto::BUMP  );
 }
 
 int KeyframePopup::update(Plugin *plugin, KeyFrame *keyframe)
 {
+       gui->get_relative_cursor(popx, popy);
        key_show->set_text(_("Show Plugin Settings"));
        this->keyframe_plugin = plugin;
        this->keyframe_auto = keyframe;
@@ -111,6 +115,7 @@ int KeyframePopup::update(Plugin *plugin, KeyFrame *keyframe)
 
 int KeyframePopup::update(Automation *automation, Autos *autos, Auto *auto_keyframe)
 {
+       gui->get_relative_cursor(popx, popy);
        key_show->set_text(_(GWindowGUI::auto_text[autos->autoidx]));
        this->keyframe_plugin = 0;
        this->keyframe_automation = automation;
@@ -155,10 +160,12 @@ void KeyframePopup::handle_curve_mode(Autos *autos, Auto *auto_keyframe)
                add_item(key_linear);
                add_item(key_free_t);
                add_item(key_free);
+               add_item(key_bump);
                key_mode_displayed = true;
        }
        else if(key_mode_displayed && (!autos || autos->get_type() != AUTOMATION_TYPE_FLOAT))
        { // remove additional menu entries
+               remove_item(key_bump);
                remove_item(key_free);
                remove_item(key_free_t);
                remove_item(key_linear);
@@ -172,6 +179,7 @@ void KeyframePopup::handle_curve_mode(Autos *autos, Auto *auto_keyframe)
                key_linear->toggle_mode((FloatAuto*)auto_keyframe);
                key_free_t->toggle_mode((FloatAuto*)auto_keyframe);
                key_free  ->toggle_mode((FloatAuto*)auto_keyframe);
+               key_bump  ->toggle_mode((FloatAuto*)auto_keyframe);
        }
        activate();
 }
@@ -192,7 +200,7 @@ int KeyframePopupDelete::handle_event()
        mwindow->undo->update_undo_before(_("delete keyframe"), 0);
        mwindow->speed_before();
        delete popup->keyframe_auto;
-       mwindow->speed_after(1);
+       mwindow->speed_after(1, 1);
        mwindow->undo->update_undo_after(_("delete keyframe"), LOAD_ALL);
 
        mwindow->save_backup();
@@ -238,9 +246,15 @@ int KeyframePopupShow::handle_event()
 {
        MWindowGUI *mgui = mwindow->gui;
        CWindowGUI *cgui = mwindow->cwindow->gui;
-       int cx = mgui->get_relative_cursor_x()+15, cy = mgui->get_relative_cursor_y()-15;
-       delete mgui->keyvalue_popup;
-       mgui->keyvalue_popup = 0;
+       int cx = popup->popx, cy = popup->popy;
+       int xmargin = mgui->get_w() - xS(200);
+       int ymargin = mgui->get_h() - yS(50);
+       if( cx > xmargin ) cx = xmargin;
+       if( cy > ymargin ) cy = ymargin;
+       xmargin = xS(15);  ymargin = yS(15);
+       if( cx < xmargin ) cx = xmargin;
+       if( cy < ymargin ) cy = ymargin;
+       mgui->close_keyvalue_popup();
 
        if( popup->keyframe_plugin ) {
                mwindow->update_plugin_guis();
@@ -278,7 +292,7 @@ int KeyframePopupShow::handle_event()
                                mgui->add_subwindow(mode);
                                mode->create_objects();
                                mode->activate_menu();
-                               mgui->keyvalue_popup = mode;
+                               mgui->open_keyvalue_popup(mode);
                        break; }
 
                        case AUTOMATION_PAN: {
@@ -286,38 +300,44 @@ int KeyframePopupShow::handle_event()
                                mgui->add_subwindow(pan);
                                pan->create_objects();
                                pan->activate(cx, cy);
-                               mgui->keyvalue_popup = pan;
+                               mgui->open_keyvalue_popup(pan);
                        break; }
 
                        case AUTOMATION_FADE: {
+                               FloatAuto *fade_auto = mwindow->get_float_auto(patchgui, AUTOMATION_FADE);
+                               int bump = fade_auto->is_bump();
                                switch( patchgui->data_type ) {
                                case TRACK_AUDIO: {
-                                       AKeyFadePatch *fade = new AKeyFadePatch(mwindow, (APatchGUI *)patchgui, cx, cy);
+                                       AKeyFadePatch *fade = new AKeyFadePatch(mwindow,
+                                                       (APatchGUI *)patchgui, bump, cx, cy);
                                        mgui->add_subwindow(fade);
                                        fade->create_objects();
-                                       mgui->keyvalue_popup = fade;
+                                       mgui->open_keyvalue_popup(fade);
                                        break; }
                                case TRACK_VIDEO: {
-                                       VKeyFadePatch *fade = new VKeyFadePatch(mwindow, (VPatchGUI *)patchgui, cx, cy);
+                                       VKeyFadePatch *fade = new VKeyFadePatch(mwindow,
+                                                       (VPatchGUI *)patchgui, bump, cx, cy);
                                        mgui->add_subwindow(fade);
                                        fade->create_objects();
-                                       mgui->keyvalue_popup = fade;
+                                       mgui->open_keyvalue_popup(fade);
                                        break; }
                                }
                                break; }
 
                        case AUTOMATION_SPEED: {
-                               KeySpeedPatch *speed = new KeySpeedPatch(mwindow, patchgui, cx, cy);
+                               FloatAuto *speed_auto = mwindow->get_float_auto(patchgui, AUTOMATION_SPEED);
+                               int bump = speed_auto->is_bump();
+                               KeySpeedPatch *speed = new KeySpeedPatch(mwindow, patchgui, bump, cx, cy);
                                mgui->add_subwindow(speed);
                                speed->create_objects();
-                               mgui->keyvalue_popup = speed;
+                               mgui->open_keyvalue_popup(speed);
                                break; }
 
                        case AUTOMATION_MUTE: {
                                KeyMutePatch *mute = new KeyMutePatch(mwindow, (APatchGUI *)patchgui, cx, cy);
                                mgui->add_subwindow(mute);
                                mute->create_objects();
-                               mgui->keyvalue_popup = mute;
+                               mgui->open_keyvalue_popup(mute);
                                break; }
                        }
                        break; }
@@ -452,13 +472,14 @@ KeyframePopupCurveMode::KeyframePopupCurveMode(
 KeyframePopupCurveMode::~KeyframePopupCurveMode() { }
 
 
-const charKeyframePopupCurveMode::get_labeltext(int mode)
+const char *KeyframePopupCurveMode::get_labeltext(int mode)
 {
        switch(mode) {
        case FloatAuto::SMOOTH: return _("smooth curve");
        case FloatAuto::LINEAR: return _("linear segments");
        case FloatAuto::TFREE:  return _("tangent edit");
        case FloatAuto::FREE:   return _("disjoint edit");
+       case FloatAuto::BUMP:   return _("bump edit");
        }
        return _("misconfigured");
 }
@@ -574,9 +595,7 @@ KeyMuteValue::KeyMuteValue(KeyMutePatch *key_mute_patch)
 int KeyMuteValue::button_release_event()
 {
        BC_CheckBox::button_release_event();
-       MWindowGUI *mgui = key_mute_patch->mwindow->gui;
-       delete mgui->keyvalue_popup;
-       mgui->keyvalue_popup = 0;
+       key_mute_patch->mwindow->gui->close_keyvalue_popup();
        return 1;
 }
 
@@ -603,29 +622,61 @@ int KeyMuteValue::handle_event()
        return 1;
 }
 
-KeySpeedPatch::KeySpeedPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
- : BC_SubWindow(x,y, 200,20, GWindowGUI::auto_colors[AUTOMATION_SPEED])
+KeySpeedPatch::KeySpeedPatch(MWindow *mwindow, PatchGUI *gui,
+               int bump, int x, int y)
+ : BC_SubWindow(x,y, xS(200)+4, yS(bump ? 50 : 24)+4,
+               GWindowGUI::auto_colors[AUTOMATION_SPEED])
 {
        this->mwindow = mwindow;
-       this->patch = patch;
+       this->gui = gui;
+       need_undo = 1;
+}
+KeySpeedPatch::~KeySpeedPatch()
+{
 }
 
 void KeySpeedPatch::create_objects()
 {
-       int x = 0, y = 0;
-       float v = mwindow->get_float_auto(patch, AUTOMATION_SPEED)->get_value();
-       add_subwindow(key_speed_text = new KeySpeedText(this, x, y, 64, v));
+       int x = 2, x1 = x, y = 2, dy = 0;
+       FloatAuto *speed_auto = mwindow->get_float_auto(gui, AUTOMATION_SPEED);
+       float v = speed_auto->get_value(gui->edge);
+       add_subwindow(key_speed_text = new KeySpeedText(this, x, y, xS(64), v));
        x += key_speed_text->get_w();
+       dy = bmax(dy, key_speed_text->get_h());
        VFrame **lok_images = mwindow->theme->get_image_set("lok");
-       int w1 = get_w() - x - lok_images[0]->get_w();
+       int w1 = get_w()-2 - x - lok_images[0]->get_w();
        add_subwindow(key_speed_slider = new KeySpeedSlider(this, x, y, w1, v));
        x += key_speed_slider->get_w();
+       dy = bmax(dy, key_speed_slider->get_h());
        add_subwindow(key_speed_ok = new KeySpeedOK(this, x, y, lok_images));
+       dy = bmax(dy, key_speed_ok->get_h());
+       if( speed_auto->is_bump() ) {
+               y += dy;
+               set_color(get_resources()->get_bg_color());
+               draw_box(0,y, get_w(),get_h());
+               add_subwindow(auto_edge = new KeySpeedAutoEdge(mwindow, this, x1, y));
+               x1 += auto_edge->get_w() + xS(15);
+               add_subwindow(auto_span = new KeySpeedAutoSpan(mwindow, this, x1, y));
+       }
+       draw_3d_border(0,0, get_w(), get_h(), 0);
        activate();
        show_window();
        mwindow->speed_before();
 }
 
+void KeySpeedPatch::set_edge(int edge)
+{
+       gui->edge = edge;
+       FloatAuto *speed_auto = mwindow->get_float_auto(gui, AUTOMATION_SPEED);
+       float v = speed_auto->get_value(edge);
+       update(v);
+}
+
+void KeySpeedPatch::set_span(int span)
+{
+       gui->span = span;
+}
+
 void KeySpeedPatch::update(float v)
 {
        key_speed_text->update(v);
@@ -635,24 +686,26 @@ void KeySpeedPatch::update(float v)
 
 void KeySpeedPatch::update_speed(float v)
 {
-       patch->change_source = 1;
-       double position = mwindow->edl->local_session->get_selectionstart(1);
-       Track *track = patch->track;
+       Track *track = gui->track;
+       if( !track->is_armed() ) return;
        Autos *speed_autos = track->automation->autos[AUTOMATION_SPEED];
-       int need_undo = !speed_autos->auto_exists_for_editing(position);
-
-       mwindow->undo->update_undo_before(_("speed"), need_undo ? 0 : this);
+       double position = mwindow->edl->local_session->get_selectionstart(1);
        FloatAuto *current = (FloatAuto*)speed_autos->get_auto_for_editing(position);
-       float change = v - current->get_value();
-       current->set_value(v);
-       if( track->is_ganged() && track->is_armed() ) {
-               TrackCanvas *track_canvas = patch->patchbay->pane->canvas;
+       float change = v - current->get_value(gui->edge);
+       if( !change ) return;
+       gui->change_source = 1;
+       if( need_undo ) {
+               need_undo = 0;
+               mwindow->undo->update_undo_before(_("speed"), this);
+       }
+       current->bump_value(v, gui->edge, gui->span);
+       if( track->is_ganged() ) {
+               TrackCanvas *track_canvas = gui->patchbay->pane->canvas;
                track_canvas->fill_ganged_autos(-1, change, track, current);
                track_canvas->update_ganged_autos(0, track, current);
                track_canvas->clear_ganged_autos();
        }
-       mwindow->undo->update_undo_after(_("speed"), LOAD_AUTOMATION+LOAD_EDITS);
-       patch->change_source = 0;
+       gui->change_source = 0;
 
        mwindow->sync_parameters(CHANGE_PARAMS);
        if(mwindow->edl->session->auto_conf->autos[AUTOMATION_SPEED]) {
@@ -669,11 +722,13 @@ KeySpeedOK::KeySpeedOK(KeySpeedPatch *key_speed_patch, int x, int y, VFrame **im
 int KeySpeedOK::handle_event()
 {
        MWindow *mwindow = key_speed_patch->mwindow;
-       mwindow->speed_after(1);
+       mwindow->speed_after(1, 1);
+       if( !key_speed_patch->need_undo ) {
+               mwindow->undo->update_undo_after(_("speed"),
+                       LOAD_AUTOMATION + LOAD_EDITS + LOAD_TIMEBAR);
+       }
        mwindow->resync_guis();
-       MWindowGUI *mgui = mwindow->gui;
-       delete mgui->keyvalue_popup;
-       mgui->keyvalue_popup = 0;
+       mwindow->gui->close_keyvalue_popup();
        return 1;
 }
 
@@ -717,3 +772,36 @@ int KeySpeedSlider::handle_event()
        return 1;
 }
 
+KeySpeedAutoEdge::KeySpeedAutoEdge(MWindow *mwindow,
+               KeySpeedPatch *patch, int x, int y)
+ : BC_Toggle(x, y, mwindow->theme->get_image_set("bump_edge"),
+                patch->gui->edge,_("Edge"))
+{
+       this->mwindow = mwindow;
+       this->patch = patch;
+       set_tooltip(_("Bump uses left edge"));
+}
+
+int KeySpeedAutoEdge::handle_event()
+{
+       patch->set_edge(get_value());
+       return 1;
+}
+
+KeySpeedAutoSpan::KeySpeedAutoSpan(MWindow *mwindow,
+               KeySpeedPatch *patch, int x, int y)
+ : BC_Toggle(x, y, mwindow->theme->get_image_set("bump_span"),
+                patch->gui->span,_("Span"))
+{
+       this->mwindow = mwindow;
+       this->patch = patch;
+       set_tooltip(_("Bump spans to next"));
+}
+
+int KeySpeedAutoSpan::handle_event()
+
+{
+       patch->set_span(get_value());
+       return 1;
+}
+
index 171c4cfc4ef2f3ab655e99493cf93f5657587c0e..16342eb0438810e5909782301ded4b386cb15e80 100644 (file)
@@ -55,6 +55,7 @@ public:
        Automation *keyframe_automation;
        Auto *keyframe_auto;
        BC_MenuItem *key_mbar;
+       int popx, popy;
 
 private:
        KeyframePopupDelete *key_delete;
@@ -66,6 +67,7 @@ private:
        KeyframePopupCurveMode *key_linear;
        KeyframePopupCurveMode *key_free_t;
        KeyframePopupCurveMode *key_free;
+       KeyframePopupCurveMode *key_bump;
        bool key_edit_displayed;
        bool key_mode_displayed;
 
@@ -192,16 +194,23 @@ public:
 class KeySpeedPatch : public BC_SubWindow
 {
 public:
-       KeySpeedPatch(MWindow *mwindow, PatchGUI *patch, int x, int y);
+       KeySpeedPatch(MWindow *mwindow, PatchGUI *gui,
+                       int bump, int x, int y);
+       ~KeySpeedPatch();
        void create_objects();
        void update(float v);
+       void set_edge(int edge);
+       void set_span(int span);
        void update_speed(float v);
 
        MWindow *mwindow;
-       PatchGUI *patch;
+       PatchGUI *gui;
        KeySpeedSlider *key_speed_slider;
        KeySpeedText *key_speed_text;
        KeySpeedOK *key_speed_ok;
+       KeySpeedAutoEdge *auto_edge;
+       KeySpeedAutoSpan *auto_span;
+       int need_undo;
 };
 
 class KeySpeedOK : public BC_Button
@@ -234,4 +243,22 @@ public:
        KeySpeedPatch *key_speed_patch;
 };
 
+class KeySpeedAutoEdge : public BC_Toggle
+{
+public:
+       KeySpeedAutoEdge(MWindow *mwindow, KeySpeedPatch *patch, int x, int y);
+       int handle_event();
+       MWindow *mwindow;
+       KeySpeedPatch *patch;
+};
+
+class KeySpeedAutoSpan : public BC_Toggle
+{
+public:
+       KeySpeedAutoSpan(MWindow *mwindow, KeySpeedPatch *patch, int x, int y);
+       int handle_event();
+       MWindow *mwindow;
+       KeySpeedPatch *patch;
+};
+
 #endif
index 55856e01a492bafa4d2fd1ce441b9e4ec36396c7..7764c18dc1d9efb6d63ce1dd4322437159dfe029 100644 (file)
@@ -37,5 +37,7 @@ class KeySpeedPatch;
 class KeySpeedOK;
 class KeySpeedText;
 class KeySpeedSlider;
+class KeySpeedAutoEdge;
+class KeySpeedAutoSpan;
 
 #endif
index 211b8767ff75db8f39965ea6a8247e2bec1cb543..ad3626bf13608f1c7b3bac7c217d6b66fa82d41c 100644 (file)
@@ -272,7 +272,9 @@ void Labels::copy_from(Labels *labels)
 
        for(Label *current = labels->first; current; current = NEXT)
        {
-               append(new Label(edl, this, current->position, current->textstr));
+               Label *new_label = new Label(edl, this, current->position, current->textstr);
+               new_label->orig_id = current->orig_id;
+               append(new_label);
        }
 }
 
@@ -460,6 +462,13 @@ Label* Labels::next_label(double position)
        return current;
 }
 
+Label* Labels::get_label(int id)
+{
+       Label *current = first;
+       while( current && current->orig_id != id ) current = NEXT;
+       return current;
+}
+
 int Labels::insert(double start, double length)
 {      // shift every label including the first one back
        Label *current;
@@ -541,6 +550,8 @@ Label* Labels::label_of(double position)
 Label::Label()
  : ListItem<Label>()
 {
+       id = EDL::next_id();
+       orig_id = id;
 }
 
 Label::Label(EDL *edl, Labels *labels, double position, const char *textstr)
@@ -550,6 +561,8 @@ Label::Label(EDL *edl, Labels *labels, double position, const char *textstr)
        this->labels = labels;
        this->position = position;
        strcpy(this->textstr, textstr ? textstr : "");
+       id = EDL::next_id();
+       orig_id = id;
 }
 
 
index 31015ea43f58d13b853ae31c6ecac9097559177f..e648de5a2ed5b9da44d5aa5824dcde57ebb6120a 100644 (file)
@@ -60,6 +60,7 @@ public:
        char textstr[BCTEXTLEN];
 // Seconds
        double position;
+       int id, orig_id;
 };
 
 class Labels : public List<Label>
@@ -98,6 +99,7 @@ public:
 // Get nearest labels or 0 if start or end of timeline
        Label* prev_label(double position);
        Label* next_label(double position);
+       Label* get_label(int id);
 
        Label* label_of(double position); // first label on or after position
        TimeBar *timebar;
index 72b9b68bc9535d20c4d2fcbc81266db10912a27a..4359595baebd2fb5efc9e5894473fb0f7031849c 100644 (file)
@@ -118,8 +118,8 @@ void MainMenu::create_objects()
        filemenu->add_item(saveas = new SaveAs(mwindow));
        save->create_objects(saveas);
        saveas->set_mainmenu(this);
-       SaveProject *save_project;
-       filemenu->add_item(save_project = new SaveProject(mwindow));
+       filemenu->add_item(new SaveProject(mwindow));
+       filemenu->add_item(new SaveSession(mwindow));
 
        filemenu->add_item(record_menu_item = new RecordMenuItem(mwindow));
 #ifdef HAVE_DVB
@@ -174,11 +174,13 @@ void MainMenu::create_objects()
        keyframemenu->add_item(new CopyKeyframes(mwindow));
        keyframemenu->add_item(new PasteKeyframes(mwindow));
        keyframemenu->add_item(new ClearKeyframes(mwindow));
-       keyframemenu->add_item(new StraightenKeyframes(mwindow));
-       keyframemenu->add_item(new BendKeyframes(mwindow));
+       keyframemenu->add_item(set_auto_curves = new SetAutomationCurveMode(mwindow));
+       set_auto_curves->create_objects();
        keyframemenu->add_item(keyframe_curve_type = new KeyframeCurveType(mwindow));
        keyframe_curve_type->create_objects();
        keyframe_curve_type->update(mwindow->edl->local_session->floatauto_type);
+       keyframemenu->add_item(keyframe_create = new KeyframeCreate(mwindow));
+       keyframe_create->create_objects();
        keyframemenu->add_item(new BC_MenuItem("-"));
        keyframemenu->add_item(new CopyDefaultKeyframe(mwindow));
        keyframemenu->add_item(new PasteDefaultKeyframe(mwindow));
@@ -636,7 +638,7 @@ int DumpUndo::handle_event()
 
 // ================================================= edit
 
-Undo::Undo(MWindow *mwindow) : BC_MenuItem(_("Undo"), "z", 'z')
+Undo::Undo(MWindow *mwindow) : BC_MenuItem(_("Undo"), "z or Ctrl-z", 'z')
 {
        this->mwindow = mwindow;
 }
@@ -732,36 +734,40 @@ int ClearKeyframes::handle_event()
 }
 
 
-
-StraightenKeyframes::StraightenKeyframes(MWindow *mwindow)
- : BC_MenuItem(_("Change to linear"))
+SetAutomationCurveItem::SetAutomationCurveItem(SetAutomationCurveMode *set_curve_mode, int id)
+ : BC_MenuItem(FloatAuto::curve_name(id))
 {
-       this->mwindow = mwindow;
+       this->set_curve_mode = set_curve_mode;
+       this->id = id;
 }
 
-int StraightenKeyframes::handle_event()
+int SetAutomationCurveItem::handle_event()
 {
-       mwindow->set_automation_mode(FloatAuto::LINEAR);
+       set_curve_mode->mwindow->set_automation_mode((FloatAuto::t_mode)id);
        return 1;
 }
 
+SetAutoCurveModeMenu::SetAutoCurveModeMenu(SetAutomationCurveMode *curve_mode)
+: BC_SubMenu()
+{
+       this->curve_mode = curve_mode;
+}
 
-
-
-BendKeyframes::BendKeyframes(MWindow *mwindow)
- : BC_MenuItem(_("Change to smooth"))
+SetAutomationCurveMode::SetAutomationCurveMode(MWindow *mwindow)
+ : BC_MenuItem(_("Set curve modes..."))
 {
        this->mwindow = mwindow;
+       curve_mode_menu = 0;
 }
 
-int BendKeyframes::handle_event()
+void SetAutomationCurveMode::create_objects()
 {
-       mwindow->set_automation_mode(FloatAuto::SMOOTH);
-       return 1;
+       add_submenu(curve_mode_menu = new SetAutoCurveModeMenu(this));
+       for( int id=FloatAuto::SMOOTH; id<=FloatAuto::BUMP; ++id )
+               curve_mode_menu->add_item(new SetAutomationCurveItem(this, id));
 }
 
 
-
 KeyframeCurveType::KeyframeCurveType(MWindow *mwindow)
  : BC_MenuItem(_("Create curve type..."))
 {
@@ -775,7 +781,7 @@ KeyframeCurveType::~KeyframeCurveType()
 void KeyframeCurveType::create_objects()
 {
        add_submenu(curve_menu = new KeyframeCurveTypeMenu(this));
-       for( int i=FloatAuto::SMOOTH; i<=FloatAuto::FREE; ++i ) {
+       for( int i=FloatAuto::SMOOTH; i<=FloatAuto::BUMP; ++i ) {
                KeyframeCurveTypeItem *curve_type_item = new KeyframeCurveTypeItem(i, this);
                curve_menu->add_submenuitem(curve_type_item);
        }
@@ -821,6 +827,63 @@ int KeyframeCurveTypeItem::handle_event()
 }
 
 
+KeyframeCreateItem::KeyframeCreateItem(KeyframeCreate *keyframe_create,
+                       const char *text, int mask)
+ : BC_MenuItem(text)
+{
+       this->keyframe_create = keyframe_create;
+       this->mask = mask;
+}
+
+int KeyframeCreateItem::handle_event()
+{
+       MWindow *mwindow = keyframe_create->mwindow;
+       int mode = mwindow->edl->local_session->floatauto_type;
+       int mask = this->mask;
+       if( !mask ) { // visible
+               int *autos = mwindow->edl->session->auto_conf->autos;
+               int modes = (1<<AUTOMATION_FADE) + (1<<AUTOMATION_SPEED) + 
+                       (7<<AUTOMATION_CAMERA_X) + (7<<AUTOMATION_PROJECTOR_X);
+               for( int i=0; i<AUTOMATION_TOTAL; modes>>=1, ++i ) {
+                       if( !(modes & 1) ) continue;
+                       if( autos[i] ) mask |= (1<<i);
+               }
+       }
+       mwindow->create_keyframes(mask, mode);
+       return 1;
+}
+
+KeyframeCreateMenu::KeyframeCreateMenu(KeyframeCreate *keyframe_create)
+: BC_SubMenu()
+{
+       this->keyframe_create = keyframe_create;
+}
+
+KeyframeCreate::KeyframeCreate(MWindow *mwindow)
+ : BC_MenuItem(_("Create keyframes..."))
+{
+       this->mwindow = mwindow;
+       keyframe_create_menu = 0;
+}
+
+void KeyframeCreate::create_objects()
+{
+       add_submenu(keyframe_create_menu = new KeyframeCreateMenu(this));
+       keyframe_create_menu->add_item(new KeyframeCreateItem(this, _("Visible"), 0));
+       keyframe_create_menu->add_item(new KeyframeCreateItem(this, _("Fade"),
+                               (1<<AUTOMATION_FADE)));
+       keyframe_create_menu->add_item(new KeyframeCreateItem(this, _("Speed"),
+                               (1<<AUTOMATION_SPEED)));
+       keyframe_create_menu->add_item(new KeyframeCreateItem(this, _("Camera XYZ"),
+                               (7<<AUTOMATION_CAMERA_X)));
+       keyframe_create_menu->add_item(new KeyframeCreateItem(this, _("Projector XYZ"),
+                               (7<<AUTOMATION_PROJECTOR_X)));
+       keyframe_create_menu->add_item(new KeyframeCreateItem(this, _("Fade+Speed+XYZ"),
+                               (1<<AUTOMATION_FADE) + (1<<AUTOMATION_SPEED) + 
+                               (7<<AUTOMATION_CAMERA_X) + (7<<AUTOMATION_PROJECTOR_X)));
+}
+
+
 CutDefaultKeyframe::CutDefaultKeyframe(MWindow *mwindow)
  : BC_MenuItem(_("Cut default keyframe"), _("Alt-x"), 'x')
 {
@@ -1510,10 +1573,11 @@ int ScrubSpeed::handle_event()
 }
 
 SaveSettingsNow::SaveSettingsNow(MWindow *mwindow)
- : BC_MenuItem(_("Save settings now"),_("Ctrl-s"),'s')
+ : BC_MenuItem(_("Save settings now"),_("Ctrl-Shift-S"),'S')
 {
        this->mwindow = mwindow;
        set_ctrl(1);
+       set_shift(1);
 }
 
 int SaveSettingsNow::handle_event()
@@ -1541,7 +1605,7 @@ ShowVWindow::ShowVWindow(MWindow *mwindow)
 int ShowVWindow::handle_event()
 {
        mwindow->gui->unlock_window();
-       mwindow->show_vwindow();
+       mwindow->show_vwindow(1);
        mwindow->gui->lock_window("ShowVWindow::handle_event");
        return 1;
 }
index 3498c2adcdcab785f9537e07c2d440e38d31725a..97f9dd1c2391e666aa7ec99362343b5647394f27 100644 (file)
@@ -141,6 +141,8 @@ public:
        int total_aeffects, total_veffects;
 
        KeyframeCurveType *keyframe_curve_type;
+       KeyframeCreate *keyframe_create;
+       SetAutomationCurveMode *set_auto_curves;
        LabelsFollowEdits *labels_follow_edits;
        PluginsFollowEdits *plugins_follow_edits;
        KeyframesFollowEdits *keyframes_follow_edits;
@@ -341,22 +343,34 @@ public:
        MWindow *mwindow;
 };
 
-class StraightenKeyframes : public BC_MenuItem
+
+class SetAutomationCurveItem : public BC_MenuItem
 {
 public:
-       StraightenKeyframes(MWindow *mwindow);
+       SetAutomationCurveItem(SetAutomationCurveMode *set_curve_mode, int id);
        int handle_event();
-       MWindow *mwindow;
+       SetAutomationCurveMode *set_curve_mode;
+       int id;
 };
 
-class BendKeyframes : public BC_MenuItem
+class SetAutoCurveModeMenu : public BC_SubMenu
 {
 public:
-       BendKeyframes(MWindow *mwindow);
-       int handle_event();
+       SetAutoCurveModeMenu(SetAutomationCurveMode *curve_mode);
+       SetAutomationCurveMode *curve_mode;
+};
+
+class SetAutomationCurveMode : public BC_MenuItem
+{
+public:
+       SetAutomationCurveMode(MWindow *mwindow);
+       void create_objects();
+
        MWindow *mwindow;
+       SetAutoCurveModeMenu *curve_mode_menu;
 };
 
+
 class KeyframeCurveType : public BC_MenuItem
 {
 public:
@@ -392,6 +406,34 @@ public:
        int handle_event();
 };
 
+class KeyframeCreateItem : public BC_MenuItem
+{
+public:
+       KeyframeCreateItem(KeyframeCreate *keyframe_create, const char *text, int mask);
+       int handle_event();
+
+       KeyframeCreate *keyframe_create;
+       int mask;
+};
+
+class KeyframeCreateMenu : public BC_SubMenu
+{
+public:
+       KeyframeCreateMenu(KeyframeCreate *keyframe_create);
+       KeyframeCreate *keyframe_create;
+};
+
+class KeyframeCreate : public BC_MenuItem
+{
+public:
+       KeyframeCreate(MWindow *mwindow);
+       void create_objects();
+
+       MWindow *mwindow;
+       KeyframeCreateMenu *keyframe_create_menu;
+};
+
+
 class CutDefaultKeyframe : public BC_MenuItem
 {
 public:
index 426ab487e1f2e21629a1af45e508dd880a424dfb..e9c3ffe02c23a453c8638e60f8ebefaf520b4c61 100644 (file)
@@ -48,11 +48,15 @@ class CutKeyframes;
 class CopyKeyframes;
 class PasteKeyframes;
 class ClearKeyframes;
-class StraightenKeyframes;
-class BendKeyframes;
+class SetAutomationCurveItem;
+class SetAutoCurveModeMenu;
+class SetAutomationCurveMode;
 class KeyframeCurveType;
 class KeyframeCurveTypeMenu;
 class KeyframeCurveTypeItem;
+class KeyframeCreateItem;
+class KeyframeCreateMenu;
+class KeyframeCreate;
 class CutDefaultKeyframe;
 class CopyDefaultKeyframe;
 class PasteDefaultKeyframe;
index 485a13df53d219630affebc33ec0c5ad19f1a3fd..7d582c46d59e65d7b32e2a0993067a69664834af 100644 (file)
@@ -36,6 +36,7 @@
 #include "mwindow.h"
 #include "mwindowgui.h"
 #include "plugin.h"
+#include "transition.h"
 
 MainSession::MainSession(MWindow *mwindow)
 {
@@ -51,6 +52,7 @@ MainSession::MainSession(MWindow *mwindow)
        current_operation = NO_OPERATION;
        drag_pluginservers = new ArrayList<PluginServer*>;
        drag_plugin = 0;
+       drag_transition = 0;
        drag_assets = new ArrayList<Indexable*>;
        drag_auto_gang = new ArrayList<Auto*>;
        drag_clips = new ArrayList<EDL*>;
@@ -221,17 +223,18 @@ void MainSession::default_window_positions(int window_config)
                        }
                }
                if( left_w > 0 ) {
+                       int min_x = INT_MAX;
                        for( int s=0; s<xin_screens; ++s ) {
                                if( display_info.xinerama_geometry(s, x, y, w, h) )
                                        continue;
-                               if( !y && x == left_w ) {
+                               if( !y && x >= left_w && x < min_x ) {
+                                       min_x = x;
                                        right_w = w;
                                        screens = 2;
-                                       break;
                                }
                        }
                        if( window_config == 1 ) {
-                               root_x = left_w;
+                               root_x = min_x;
                                root_w = right_w;
                        }
                        else {
@@ -656,6 +659,10 @@ Track *MainSession::drag_handle_track()
        case DRAG_PLUGINHANDLE2:
                track = drag_plugin->edits->track;
                break;
+       case DRAG_TRANSNHANDLE1:
+       case DRAG_TRANSNHANDLE2:
+               track = drag_transition->edits->track;
+               break;
        }
        return track;
 }
index 58115d69fc313b3b1b13d069ec0d04baef702149..e8d31db67e4e07f2b6c569e91fe7adb83fd1bf2c 100644 (file)
@@ -38,6 +38,7 @@
 #include "pluginset.inc"
 #include "pluginserver.inc"
 #include "track.inc"
+#include "transition.inc"
 #include "vwindowgui.inc"
 
 // Options not in EDL but not changed in preferences
@@ -73,6 +74,7 @@ public:
 // Item being dragged
        ArrayList <PluginServer*> *drag_pluginservers;
        Plugin *drag_plugin;
+       Transition *drag_transition;
 // When trim should only affect the selected edits or plugins
        Edits *trim_edits;
        ArrayList<Indexable*> *drag_assets;
index 0a734958ca99b948e33f908576349ebdea942943..754183c29e85ce21b9b24c6504880bbbd6724813 100644 (file)
@@ -61,6 +61,8 @@ enum
        DRAG_PLUGINKEY,
        DRAG_PLUGINHANDLE1,        // Waiting to move out of drag threshold
        DRAG_PLUGINHANDLE2,         // Dragging outside drag threshold
+       DRAG_TRANSNHANDLE1,
+       DRAG_TRANSNHANDLE2,
        DRAG_SPEED,
        DRAG_GROUP,
        GROUP_TOGGLE,
index dd06f3cd7352227394ce0f7f3a3ea99422e2633d..c19a6ada63a00de0b368b5fb6d5f00d0f3c1e375 100644 (file)
@@ -187,7 +187,9 @@ int MainUndo::redo_load_flags()
 
 int MainUndo::undo()
 {
+       mwindow->gui->close_keyvalue_popup();
        mwindow->undo_commercial();
+
        UndoStackItem *current = undo_stack->current;
        if( current ) {
                undo_stack->current = next_undo();
@@ -217,14 +219,14 @@ int MainUndo::undo()
                }
        }
 
+       mwindow->reset_caches(1);
        reset_creators();
-       mwindow->reset_caches();
        return 0;
 }
 
-
 int MainUndo::redo()
 {
+       mwindow->gui->close_keyvalue_popup();
        UndoStackItem *current = next_redo();
        if( current ) {
                undo_stack->current = current;
@@ -244,8 +246,8 @@ int MainUndo::redo()
                                update_caption(current ? current->get_description() : "");
                }
        }
+       mwindow->reset_caches(1);
        reset_creators();
-       mwindow->reset_caches();
 //dump();
        return 0;
 }
@@ -254,9 +256,7 @@ int MainUndo::redo()
 // Here the master EDL loads
 int MainUndo::load_from_undo(FileXML *file, uint32_t load_flags)
 {
-       delete mwindow->gui->keyvalue_popup;
-       mwindow->gui->keyvalue_popup = 0;
-
+       mwindow->hide_plugins();
        if( load_flags & LOAD_SESSION ) {
                mwindow->gui->unlock_window();
                mwindow->close_mixers();
index a8851d54484201d969ff15f72d49a11b402753a5..cf16cd9354528066b1f040cbe60055c2d7df0aa1 100644 (file)
@@ -303,7 +303,7 @@ MWindow::~MWindow()
        gui->del_keyboard_listener(
                (int (BC_WindowBase::*)(BC_WindowBase *))
                &MWindowGUI::keyboard_listener);
-       reset_caches();
+       reset_caches(0);
 #if 0
 // release the hounds
        if( awindow && awindow->gui ) awindow->gui->close(0);
@@ -2919,7 +2919,7 @@ void MWindow::run()
        run_lock->unlock();
 }
 
-void MWindow::show_vwindow()
+void MWindow::show_vwindow(int raise)
 {
        int total_running = 0;
        session->show_vwindow = 1;
@@ -2929,19 +2929,17 @@ void MWindow::show_vwindow()
        for(int j = 0; j < vwindows.size(); j++) {
                VWindow *vwindow = vwindows[j];
                if( !vwindow->is_running() ) continue;
+               total_running++;
+               if( !raise && !vwindow->gui->is_hidden() ) continue;
                vwindow->gui->lock_window("MWindow::show_vwindow");
                vwindow->gui->show_window(0);
                vwindow->gui->raise_window();
                vwindow->gui->flush();
                vwindow->gui->unlock_window();
-               total_running++;
        }
-
 // If no windows visible
-       if(!total_running)
-       {
+       if( !total_running )
                get_viewer(1, DEFAULT_VWINDOW);
-       }
 
        gui->mainmenu->show_vwindow->set_checked(1);
 }
@@ -2968,6 +2966,7 @@ void MWindow::show_cwindow()
 {
        session->show_cwindow = 1;
        cwindow->show_window();
+       cwindow->gui->tool_panel->raise_tool();
        gui->mainmenu->show_cwindow->set_checked(1);
 }
 
@@ -3015,8 +3014,8 @@ void MWindow::restore_windows()
                        vwindow->gui->unlock_window();
                }
        }
-       else
-               show_vwindow();
+       else 
+               show_vwindow(0);
 
        if( !session->show_awindow && !awindow->gui->is_hidden() ) {
                awindow->gui->lock_window("MWindow::restore_windows");
@@ -3741,8 +3740,7 @@ void MWindow::update_project(int load_mode)
        if( load_mode == LOADMODE_REPLACE ||
            load_mode == LOADMODE_REPLACE_CONCATENATE ) {
                edl->session->timecode_offset = 0;
-               delete gui->keyvalue_popup;
-               gui->keyvalue_popup = 0;
+               gui->close_keyvalue_popup();
                gui->load_panes();
        }
 
@@ -4089,18 +4087,18 @@ void MWindow::update_preferences(Preferences *prefs)
        if( prefs != preferences )
                preferences->copy_from(prefs);
        if( cwindow->playback_engine )
-               cwindow->playback_engine->preferences->copy_from(prefs);
+               cwindow->playback_engine->update_preferences(prefs);
        for(int i = 0; i < vwindows.size(); i++) {
                VWindow *vwindow = vwindows[i];
                if( !vwindow->is_running() ) continue;
                if( vwindow->playback_engine )
-                       vwindow->playback_engine->preferences->copy_from(prefs);
+                       vwindow->playback_engine->update_preferences(prefs);
        }
        for(int i = 0; i < zwindows.size(); i++) {
                ZWindow *zwindow = zwindows[i];
                if( !zwindow->is_running() ) continue;
                if( zwindow->zgui->playback_engine )
-                       zwindow->zgui->playback_engine->preferences->copy_from(prefs);
+                       zwindow->zgui->playback_engine->update_preferences(prefs);
        }
 }
 
@@ -4475,31 +4473,24 @@ int MWindow::create_aspect_ratio(float &w, float &h, int width, int height)
        return 0;
 }
 
-void MWindow::reset_caches()
+void MWindow::reset_caches(int locked)
 {
-       int locked  = gui->get_window_lock();
        if( locked ) gui->unlock_window();
        awindow->gui->stop_vicon_drawing(1);
-       frame_cache->remove_all();
-       wave_cache->remove_all();
-       audio_cache->remove_all();
-       video_cache->remove_all();
-       if( cwindow->playback_engine ) {
-               if( cwindow->playback_engine->audio_cache )
-                       cwindow->playback_engine->audio_cache->remove_all();
-               if( cwindow->playback_engine->video_cache )
-                       cwindow->playback_engine->video_cache->remove_all();
-       }
+       if( cwindow->playback_engine )
+               cwindow->playback_engine->create_cache();
        for(int i = 0; i < vwindows.size(); i++) {
                VWindow *vwindow = vwindows[i];
                if( !vwindow->is_running() ) continue;
                if( !vwindow->playback_engine ) continue;
-               if( vwindow->playback_engine->audio_cache )
-                       vwindow->playback_engine->audio_cache->remove_all();
-               if( vwindow->playback_engine->video_cache )
-                       vwindow->playback_engine->video_cache->remove_all();
+               vwindow->playback_engine->create_cache();
        }
-       if( locked ) gui->lock_window("MWindow::reset_caches");
+       gui->lock_window("MWindow::reset_caches");
+       frame_cache->remove_all();
+       wave_cache->remove_all();
+       audio_cache->remove_all();
+       video_cache->remove_all();
+       if( !locked ) gui->unlock_window();
 }
 
 void MWindow::remove_from_caches(Indexable *idxbl)
index da5b8f4c1615ef2eeaa5a75e63a5c34b9329213a..b31f2642141ceddad78638c31c1210bd84ab20ef 100644 (file)
@@ -209,7 +209,7 @@ public:
        void media_to_clip();
        int create_ref(Asset *asset, EDL *ref);
 // Show windows
-       void show_vwindow();
+       void show_vwindow(int raise);
        void show_awindow();
        void show_lwindow();
        void show_cwindow();
@@ -447,6 +447,7 @@ public:
        void clear_hard_edges();
        int clear_hard_edges(double start, double end);
        void clear_select();
+       void select_edits();
        void concatenate_tracks();
        int copy_flags(int copy_flags=COPY_CLIPBOARD);
        void copy();
@@ -564,7 +565,7 @@ public:
        void remove_indexfile(Indexable *indexable);
        void rebuild_indices();
 // Asset removal from caches
-       void reset_caches();
+       void reset_caches(int locked);
        void remove_from_caches(Indexable *idxbl);
        void remove_assets_from_project(int push_undo, int redraw, int delete_indexes,
                ArrayList<Indexable*> *drag_assets /* mwindow->session->drag_assets */,
@@ -613,6 +614,7 @@ public:
 // in the clipboard.
        int paste_default_keyframe();
        int clear_default_keyframe();
+       void create_keyframes(int mask, int mode);
 
        FloatAuto* get_float_auto(PatchGUI *patch,int idx);
        IntAuto* get_int_auto(PatchGUI *patch,int idx);
@@ -621,6 +623,7 @@ public:
 
        int modify_edithandles();
        int modify_pluginhandles();
+       int modify_transnhandles();
        void finish_modify_handles();
        void rescale_proxy(EDL *clip, int orig_scale, int new_scale);
        void add_proxy(ArrayList<Indexable*> *orig_assets,
@@ -838,8 +841,8 @@ public:
        static void add_plugins(ArrayList<PluginServer*> &plugins);
        static void delete_plugins();
        void speed_before();
-       int speed_after(int done);
-       int normalize_speed(EDL *old_edl, EDL *new_edl);
+       int speed_after(int done, int edit_speed);
+       int normalize_speed(EDL *old_edl, EDL *new_edl, int edit_speed);
        int get_cpus(int out_w, int out_h);
        int get_cpus();
 //
index d424d60879335f2f4dc267f2b57dedb9f88f47dc..003844fe9a61698083240ba6f8dbd0a6ae059676 100644 (file)
@@ -289,7 +289,8 @@ void MWindow::clear_entry()
 
        edl->optimize();
        save_backup();
-       undo_after(_("clear"), LOAD_EDITS | LOAD_TIMEBAR);
+       undo_after(_("clear"),
+                       LOAD_AUTOMATION + LOAD_EDITS + LOAD_TIMEBAR);
 
        restart_brender();
        update_plugin_guis();
@@ -336,7 +337,7 @@ void MWindow::set_automation_mode(int mode)
                edl->local_session->get_selectionstart(),
                edl->local_session->get_selectionend(),
                mode);
-       int changed_edl = speed_after(1);
+       int changed_edl = speed_after(1, 1);
        save_backup();
        char string[BCSTRLEN];
        sprintf(string,"set %s", FloatAuto::curve_name(mode));
@@ -352,7 +353,7 @@ void MWindow::clear_automation()
        speed_before();
        edl->tracks->clear_automation(edl->local_session->get_selectionstart(),
                edl->local_session->get_selectionend());
-       int changed_edl = speed_after(1);
+       int changed_edl = speed_after(1, 1);
        save_backup();
        undo_after(_("clear keyframes"),
                !changed_edl ? LOAD_AUTOMATION :
@@ -365,7 +366,7 @@ int MWindow::clear_default_keyframe()
        undo_before();
        speed_before();
        edl->tracks->clear_default_keyframe();
-       int changed_edl = speed_after(1);
+       int changed_edl = speed_after(1, 1);
        save_backup();
        undo_after(_("clear default keyframe"),
                !changed_edl ? LOAD_AUTOMATION :
@@ -425,6 +426,14 @@ void MWindow::clear_select()
        gui->draw_overlays(1);
 }
 
+void MWindow::select_edits()
+{
+       double start = edl->local_session->get_selectionstart();
+       double end = edl->local_session->get_selectionend();
+       edl->tracks->select_edits(start, end);
+       gui->draw_overlays(1);
+}
+
 void MWindow::concatenate_tracks()
 {
        undo_before();
@@ -668,7 +677,7 @@ int MWindow::cut_automation()
        copy_automation();
        edl->tracks->clear_automation(edl->local_session->get_selectionstart(),
                edl->local_session->get_selectionend());
-       int changed_edl = speed_after(1);
+       int changed_edl = speed_after(1, 1);
        save_backup();
        undo_after(_("cut keyframes"),
                !changed_edl ? LOAD_AUTOMATION :
@@ -684,7 +693,7 @@ int MWindow::cut_default_keyframe()
        speed_before();
        copy_default_keyframe();
        edl->tracks->clear_default_keyframe();
-       int changed_edl = speed_after(1);
+       int changed_edl = speed_after(1, 1);
        save_backup();
        undo_after(_("cut default keyframe"),
                !changed_edl ? LOAD_AUTOMATION :
@@ -951,6 +960,34 @@ void MWindow::finish_modify_handles()
        cwindow->update(1, 0, 0, 0, 1);
 }
 
+int MWindow::modify_transnhandles()
+{
+       gui->reset_default_message();
+       gui->default_message();
+       Transition *transition = session->drag_transition;
+       if( !transition ) return 1;
+       int64_t length = transition->length;
+       Track *track = transition->edit->track;
+       int64_t start_pos = track->to_units(session->drag_start, 0);
+       int64_t end_pos = track->to_units(session->drag_position, 0);
+       length += end_pos - start_pos;
+       if( length < 0 ) length = 0;
+       if( length == transition->length ) return 0;
+
+       undo_before();
+       transition->length = length;
+       undo_after(_("trans handle"), LOAD_EDITS);
+
+       save_backup();
+       restart_brender();
+       sync_parameters(CHANGE_EDL);
+       update_plugin_guis();
+       gui->update(1, FORCE_REDRAW, 1, 1, 1, 1, 0);
+       cwindow->update(1, 0, 0, 0, 1);
+
+       return 0;
+}
+
 void MWindow::match_output_size(Track *track)
 {
        undo_before();
@@ -1326,7 +1363,8 @@ void MWindow::overwrite(EDL *source, int all)
        edl->local_session->set_selectionend(dst_start + overwrite_len);
 
        save_backup();
-       undo_after(_("overwrite"), LOAD_EDITS);
+       undo_after(_("overwrite"),
+                       LOAD_AUTOMATION + LOAD_EDITS + LOAD_TIMEBAR);
 
        restart_brender();
        update_plugin_guis();
@@ -1379,7 +1417,8 @@ void MWindow::paste(double start, Track *first_track, int clear_selection, int o
 
                save_backup();
 
-               undo_after(_("paste"), LOAD_EDITS | LOAD_TIMEBAR);
+               undo_after(_("paste"),
+                               LOAD_AUTOMATION + LOAD_EDITS + LOAD_TIMEBAR);
                restart_brender();
                update_plugin_guis();
                gui->update(1, FORCE_REDRAW, 1, 1, 0, 1, 0);
@@ -1416,7 +1455,8 @@ int MWindow::paste_assets(double position, Track *dest_track, int overwrite)
 
        save_backup();
 
-       undo_after(_("paste assets"), LOAD_EDITS);
+       undo_after(_("paste assets"),
+                       LOAD_AUTOMATION + LOAD_EDITS + LOAD_TIMEBAR);
        restart_brender();
        gui->update(1, FORCE_REDRAW, 1, 0, 0, 1, 0);
        sync_parameters(CHANGE_EDL);
@@ -1490,7 +1530,7 @@ int MWindow::paste_automation()
                edl->tracks->clear_automation(start, end);
                edl->tracks->paste_automation(start, &file, 0, 1,
                        edl->session->typeless_keyframes);
-               int changed_edl = speed_after(1);
+               int changed_edl = speed_after(1, 0);
                save_backup();
                undo_after(_("paste keyframes"),
                        !changed_edl ? LOAD_AUTOMATION :
@@ -1517,7 +1557,7 @@ int MWindow::paste_default_keyframe()
                edl->tracks->paste_automation(start, &file, 1, 0,
                        edl->session->typeless_keyframes);
 //             edl->tracks->paste_default_keyframe(&file);
-               int changed_edl = speed_after(1);
+               int changed_edl = speed_after(1, 1);
                undo_after(_("paste default keyframe"),
                        !changed_edl ? LOAD_AUTOMATION :
                                LOAD_AUTOMATION + LOAD_EDITS + LOAD_TIMEBAR);
@@ -1550,7 +1590,7 @@ int MWindow::paste_edls(ArrayList<EDL*> *new_edls, int load_mode,
 // Delete current project
        if( load_mode == LOADMODE_REPLACE ||
            load_mode == LOADMODE_REPLACE_CONCATENATE ) {
-               reset_caches();
+               reset_caches(1);
                edl->save_defaults(defaults);
                hide_plugins();
                edl->Garbage::remove_user();
@@ -1837,7 +1877,8 @@ void MWindow::paste_silence()
                edl->session->autos_follow_edits);
        edl->optimize();
        save_backup();
-       undo_after(_("silence"), LOAD_EDITS | LOAD_TIMEBAR);
+       undo_after(_("silence"),
+                       LOAD_AUTOMATION + LOAD_EDITS + LOAD_TIMEBAR);
 
        update_plugin_guis();
        restart_brender();
@@ -2208,7 +2249,8 @@ void MWindow::splice(EDL *source, int all)
        edl->local_session->set_selectionend(start + source_end - source_start);
 
        save_backup();
-       undo_after(_("splice"), LOAD_EDITS | LOAD_TIMEBAR);
+       undo_after(_("splice"),
+                       LOAD_AUTOMATION + LOAD_EDITS + LOAD_TIMEBAR);
        update_plugin_guis();
        restart_brender();
        gui->update(1, NORMAL_DRAW, 1, 1, 0, 1, 0);
@@ -2339,7 +2381,8 @@ void MWindow::trim_selection()
                edl->session->autos_follow_edits);
 
        save_backup();
-       undo_after(_("trim selection"), LOAD_EDITS | LOAD_TIMEBAR);
+       undo_after(_("trim selection"),
+                       LOAD_AUTOMATION + LOAD_EDITS + LOAD_TIMEBAR);
        update_plugin_guis();
        gui->update(1, FORCE_REDRAW, 1, 1, 1, 1, 0);
        cwindow->update(1, 0, 0, 0, 1);
@@ -2567,9 +2610,13 @@ void MWindow::cut_commercials()
 #endif
 }
 
-int MWindow::normalize_speed(EDL *old_edl, EDL *new_edl)
+int MWindow::normalize_speed(EDL *old_edl, EDL *new_edl, int edit_speed)
 {
-       int result = 0;
+       int edit_plugins = edl->session->plugins_follow_edits;
+       int edit_autos = edl->session->autos_follow_edits;
+       int edit_labels = edl->session->labels_follow_edits;
+       if( !edit_autos ) edit_speed = 0;
+       int result = 0, first_track = 1;
        Track *old_track = old_edl->tracks->first;
        Track *new_track = new_edl->tracks->first;
        for( ; old_track && new_track; old_track=old_track->next, new_track=new_track->next ) {
@@ -2583,20 +2630,107 @@ int MWindow::normalize_speed(EDL *old_edl, EDL *new_edl)
                        old_speed = (FloatAuto *)old_speed->next;
                        new_speed = (FloatAuto *)new_speed->next;
                }
-               Edit *old_edit = old_track->edits->first;
-               Edit *new_edit = new_track->edits->first;
-               for( ; old_edit && new_edit; old_edit=old_edit->next, new_edit=new_edit->next ) {
-                       int64_t edit_start = old_edit->startproject, edit_end = edit_start + old_edit->length;
-                       if( old_speed || new_speed ) {
-                               double orig_start = old_speeds->automation_integral(0, edit_start, PLAY_FORWARD);
-                               double orig_end   = old_speeds->automation_integral(0, edit_end, PLAY_FORWARD);
-                               edit_start = new_speeds->speed_position(orig_start);
-                               edit_end = new_speeds->speed_position(orig_end);
-                               result = 1;
+               if( !old_speed && !new_speed ) continue;
+               result = 1;
+               if( edit_speed ) {
+                       Autos *old_autos = old_track->automation->autos[AUTOMATION_SPEED];
+                       Autos *new_autos = new_track->automation->autos[AUTOMATION_SPEED];
+                       Auto *old_auto = old_autos ? old_autos->first : 0;
+                       for( ; old_auto; old_auto=old_auto->next ) {
+                               Auto *new_auto = new_autos->get_auto(old_auto->orig_id);
+                               if( !new_auto ) continue;
+                               int64_t auto_pos = old_auto->position;
+                               double orig_pos = old_speeds->automation_integral(0, auto_pos, PLAY_FORWARD);
+                               auto_pos = new_track->frame_align(new_speeds->speed_position(orig_pos), 1);
+                               new_auto->position = auto_pos;
                        }
+               }
+               Edit *old_edit = old_track->edits->first;
+               for( ; old_edit; old_edit=old_edit->next ) {
+                       Edit *new_edit = new_track->edits->get_edit(old_edit->orig_id);
+                       if( !new_edit ) continue;
+                       int64_t edit_start = old_edit->startproject;
+                       int64_t edit_end = edit_start + old_edit->length;
+                       double orig_start = old_speeds->automation_integral(0, edit_start, PLAY_FORWARD);
+                       double orig_end   = old_speeds->automation_integral(0, edit_end, PLAY_FORWARD);
+                       edit_start = new_track->frame_align(new_speeds->speed_position(orig_start), 1);
+                       edit_end = new_track->frame_align(new_speeds->speed_position(orig_end), 1);
                        new_edit->startproject = edit_start;
                        new_edit->length = edit_end - edit_start;
                }
+               if( first_track && old_track->is_armed() ) {
+                       Labels *old_labels = old_edl->labels;
+                       Labels *new_labels = new_edl->labels;
+                       if( edit_labels && old_labels && new_labels ) {
+                               Label *old_label = old_labels->first;
+                               for( ; old_label; old_label=old_label->next ) {
+                                       Label *new_label = new_labels->get_label(old_label->orig_id);
+                                       if( !new_label ) continue;
+                                       int64_t label_pos = old_track->to_units(old_label->position, 1);
+                                       double orig_pos = old_speeds->automation_integral(0, label_pos, PLAY_FORWARD);
+                                       label_pos = new_track->frame_align(new_speeds->speed_position(orig_pos), 1);
+                                       new_label->position = new_track->from_units(label_pos);
+                               }
+                       }
+                       first_track = 0;
+               }
+               if( edit_plugins ) {
+                       int old_size = old_track->plugin_set.size();
+                       int new_size = new_track->plugin_set.size();
+                       int n = bmin(old_size, new_size);
+                       for( int i=0; i<n; ++i ) {
+                               PluginSet *old_plugin_set = old_track->plugin_set[i];
+                               if( !old_plugin_set ) continue;
+                               PluginSet *new_plugin_set = new_track->plugin_set[i];
+                               if( !new_plugin_set ) continue;
+                               Plugin *old_plugin = (Plugin *)old_plugin_set->first;
+                               for( ; old_plugin; old_plugin=(Plugin *)old_plugin->next ) {
+                                       Plugin *new_plugin = (Plugin *)new_plugin_set->get_edit(old_plugin->orig_id);
+                                       if( !new_plugin ) continue;
+                                       int64_t plugin_start = old_plugin->startproject;
+                                       int64_t plugin_end = plugin_start + old_plugin->length;
+                                       double orig_start = old_speeds->automation_integral(0, plugin_start, PLAY_FORWARD);
+                                       double orig_end   = old_speeds->automation_integral(0, plugin_end, PLAY_FORWARD);
+                                       plugin_start = new_track->frame_align(new_speeds->speed_position(orig_start), 1);
+                                       plugin_end = new_track->frame_align(new_speeds->speed_position(orig_end), 1);
+                                       new_plugin->startproject = plugin_start;
+                                       new_plugin->length = plugin_end - plugin_start;
+                                       if( edit_autos ) {
+                                               KeyFrames *old_keyframes = old_plugin->keyframes;
+                                               if( !old_keyframes ) continue;
+                                               KeyFrames *new_keyframes = new_plugin->keyframes;
+                                               if( !new_keyframes ) continue;
+                                               Auto *old_auto = old_keyframes->first;
+                                               for( ; old_auto; old_auto=old_auto->next ) {
+                                                       Auto *new_auto = new_keyframes->get_auto(old_auto->orig_id);
+                                                       if( !new_auto ) continue;
+                                                       int64_t auto_pos = old_auto->position;
+                                                       double orig_pos = old_speeds->automation_integral(0, auto_pos, PLAY_FORWARD);
+                                                       auto_pos = new_track->frame_align(new_speeds->speed_position(orig_pos), 1);
+                                                       new_auto->position = auto_pos;
+                                                       old_auto = old_auto->next;
+                                               }
+                                       }
+                               }
+                       }
+               }
+               if( edit_autos ) { // speed must be last
+                       for( int i=0; i<AUTOMATION_SPEED; ++i ) {
+                               Autos *old_autos = old_track->automation->autos[i];
+                               if( !old_autos ) continue;
+                               Autos *new_autos = new_track->automation->autos[i];
+                               if( !new_autos ) continue;
+                               Auto *old_auto = old_autos->first;
+                               for( ; old_auto; old_auto=old_auto->next ) {
+                                       Auto *new_auto = new_autos->get_auto(old_auto->orig_id);
+                                       if( !new_auto ) continue;
+                                       int64_t auto_pos = old_auto->position;
+                                       double orig_pos = old_speeds->automation_integral(0, auto_pos, PLAY_FORWARD);
+                                       auto_pos = new_track->frame_align(new_speeds->speed_position(orig_pos), 1);
+                                       new_auto->position = auto_pos;
+                               }
+                       }
+               }
        }
        return result;
 }
@@ -2610,12 +2744,12 @@ void MWindow::speed_before()
        speed_edl->copy_all(edl);
 }
 
-int MWindow::speed_after(int done)
+int MWindow::speed_after(int done, int edit_speed)
 {
        int result = 0;
        if( speed_edl ) {
                if( done >= 0 )
-                       result = normalize_speed(speed_edl, edl);
+                       result = normalize_speed(speed_edl, edl, edit_speed);
                if( done != 0 ) {
                        speed_edl->remove_user();
                        speed_edl = 0;
@@ -2810,3 +2944,20 @@ void MWindow::mix_masters()
        save_backup();
 }
 
+void MWindow::create_keyframes(int mask, int mode)
+{
+       undo_before();
+       double start = edl->local_session->get_selectionstart();
+       edl->tracks->create_keyframes(start, mask, mode);
+       double end = edl->local_session->get_selectionend();
+       if( end != start )
+               edl->tracks->create_keyframes(end, mask, mode);
+       undo_after(_("create kyfrms"), LOAD_AUTOMATION);
+
+       restart_brender();
+       gui->update(1, NORMAL_DRAW, 0, 0, 1, 0, 0);
+       gui->activate_timeline();
+       cwindow->refresh_frame(CHANGE_EDL);
+       save_backup();
+}
+
index 9c3dc9d8fa0b5df2798f9bcbbe648ad7d0cbc1cb..5f9edd9202ec5eeb27d89294df40877f6d16c017 100644 (file)
@@ -1079,27 +1079,32 @@ int MWindowGUI::keypress_event()
        if( result ) return result;
 
        Track *this_track = 0, *first_track = 0;
-       int collapse = 0, packed = 0, overwrite = 0, plugins = 0;
+       int packed = 0, overwrite = 0, plugins = 0;
        double position = 0;
 
        switch( get_keypress() ) {
        case 'A':
-               if( !alt_down() ) {
-                       if( !ctrl_down() || !shift_down() ) break;
+               if( !alt_down() && ctrl_down() ) {
                        mwindow->edl->tracks->clear_selected_edits();
                        draw_overlays(1);
                        result = 1;
-                       break;
-               } // fall thru
+               }
+               break;
        case 'a':
-               if( !alt_down() ) break;
-               stop_transport("MWindowGUI::keypress_event 1");
-               mwindow->nearest_auto_keyframe(shift_down(),
-                       !ctrl_down() ? PLAY_FORWARD : PLAY_REVERSE);
-               result = 1;
+               if( !ctrl_down() && alt_down() ) {
+                       stop_transport("MWindowGUI::keypress_event 1");
+                       mwindow->nearest_auto_keyframe(shift_down(),
+                               !ctrl_down() ? PLAY_FORWARD : PLAY_REVERSE);
+                       result = 1;
+               }
+               else if( ctrl_down() && alt_down() ) {
+                       mwindow->select_edits();
+                       result = 1;
+               }
                break;
 
        case 'e':
+               if( ctrl_down() || alt_down() ) break;
                mwindow->toggle_editing_mode();
                result = 1;
                break;
@@ -1150,17 +1155,29 @@ int MWindowGUI::keypress_event()
                result = 1;
                break;
        case 'M':
-               collapse = 1;
+               mwindow->cut_selected_edits(0, 1);
+               result = 1;
+               break;
        case BACKSPACE:
        case 'm':
-               mwindow->cut_selected_edits(0, collapse);
+               mwindow->cut_selected_edits(0, 0);
                result = 1;
                break;
        case 'z':
-               collapse = 1;
+               if( !alt_down() ) {
+                       // z and ctrl-z both are undo, z mainmenu item
+                       if( mwindow->session->current_operation == NO_OPERATION )
+                               mwindow->undo_entry(this);
+                       result = 1;
+               }
+               else if( ctrl_down() ) {
+                       mwindow->cut_selected_edits(1, 1);
+                       result = 1;
+               }
+               break;
        case 'x':
                if( !ctrl_down() || alt_down() ) break;
-               mwindow->cut_selected_edits(1, collapse);
+               mwindow->cut_selected_edits(1, 0);
                result = 1;
                break;
 
@@ -2284,6 +2301,19 @@ void MWindowGUI::stop_transport(const char *lock_msg)
        }
 }
 
+void MWindowGUI::close_keyvalue_popup()
+{
+       if( !keyvalue_popup ) return;
+       delete keyvalue_popup;
+       keyvalue_popup = 0;
+}
+
+void MWindowGUI::open_keyvalue_popup(BC_SubWindow *popup)
+{
+       close_keyvalue_popup();
+       keyvalue_popup = popup;
+}
+
 PaneButton::PaneButton(MWindow *mwindow, int x, int y)
  : BC_Button(x, y, mwindow->theme->get_image_set("pane"))
 {
index bc3aa3a65ff2d64bb5e13fd3a7ebd5a7c87b5500..74f353eaab785f131d75d6370196e5783cf002bf 100644 (file)
@@ -161,6 +161,8 @@ public:
        void set_meter_format(int mode, int min, int max);
        void update_mixers(Track *track, int v);
        void stop_transport(const char *lock_msg);
+       void close_keyvalue_popup();
+       void open_keyvalue_popup(BC_SubWindow *popup);
 
        int translation_event();
        int resize_event(int w, int h);          // handle a resize event
index f24876bc09a11dbae1a9ff7e9e08c455ec77dc97..47e467050920d397eb5baa1c49ff8fc13d7e7d8c 100644 (file)
@@ -60,7 +60,7 @@
 // add tracks dialog
 #define HEIGHT1 yS(240)
 // offset for folder panel
-#define HEIGHT2 yS(440)
+#define HEIGHT2 yS(435)
 
 New::New(MWindow *mwindow)
 {
@@ -98,8 +98,8 @@ void New::create_new_edl()
 int New::create_new_project(int load_mode)
 {
        mwindow->stop_playback(0);
+       mwindow->reset_caches(0);
        mwindow->gui->lock_window();
-       mwindow->reset_caches();
 
        memcpy(new_edl->session->achannel_positions,
                &mwindow->preferences->channel_positions[new_edl->session->audio_channels - 1],
index dccec03a2896c3f8676a0f66b44f589b285bc090..17d02c0d3bad198b0e60f228f5403689ad93f3bc 100644 (file)
@@ -279,9 +279,11 @@ RenderPackage* PackageDispatcher::get_package(double frames_per_second,
                        result->video_start = video_position;
                        result->audio_end = result->audio_start +
                                Units::to_int64(scaled_len * default_asset->sample_rate);
+                       if( result->audio_end > audio_end ) result->audio_end = audio_end;
                        result->video_end = result->video_start +
                                Units::to_int64(scaled_len * default_asset->frame_rate);
-                       if(result->video_end == result->video_start) result->video_end++;
+                       if( result->video_end > video_end ) result->video_end = video_end;
+                       if( result->video_end == result->video_start ) result->video_end++;
                        audio_position = result->audio_end;
                        video_position = result->video_end;
                        result->audio_do = default_asset->audio_data;
index a76d736ae5839f9f03f87329bcd45238af6ad19b..1c86af68d02b5bb2d050cfa2b5a52a463c4514fb 100644 (file)
@@ -80,10 +80,20 @@ RenderPackage::~RenderPackage()
 }
 
 
+PackageFile::PackageFile(PackageRenderer *package_renderer)
+{
+       this->package_renderer = package_renderer;
+}
 
+PackageFile::~PackageFile()
+{
+}
 
-
-
+int PackageFile::write_frame_done(int64_t position)
+{
+       if( !package_renderer->package->use_brender ) return 0;
+       return package_renderer->set_video_map(position, BRender::RENDERED);
+}
 
 
 // Used by RenderFarm and in the future, Render, to do packages.
@@ -160,7 +170,7 @@ void PackageRenderer::create_output()
        else
                strncpy(asset->path, package->path, sizeof(asset->path));
 
-       file = new File;
+       file = new PackageFile(this);
        file->set_processors(preferences->processors);
        result = file->open_file(preferences, asset, 0, 1);
 
@@ -396,13 +406,6 @@ void PackageRenderer::do_video()
 
                                        if( video_write_position >= video_write_length ) {
                                                result = file->write_video_buffer(video_write_position);
-// Update the brender map after writing the files.
-                                               if( package->use_brender ) {
-                                                       for( int i = 0; i < video_write_position && !result; i++ ) {
-                                                               result = set_video_map(video_position + 1 - video_write_position + i,
-                                                                       BRender::RENDERED);
-                                                       }
-                                               }
                                                video_write_position = 0;
                                        }
                                }
@@ -438,12 +441,6 @@ void PackageRenderer::stop_output()
                delete compressed_output;
                if( video_write_position )
                        file->write_video_buffer(video_write_position);
-               if( package->use_brender ) {
-                       for( int i = 0; i < video_write_position && !error; i++ ) {
-                               error = set_video_map(video_position - video_write_position + i,
-                                       BRender::RENDERED);
-                       }
-               }
                video_write_position = 0;
                if( !error ) file->stop_video_thread();
                if( mwindow ) {
index 3c444b2e9f296a6f5a1bff689952a0733283ca53..828194597269729d7e7d03a1b8720a0a364557ca 100644 (file)
 #include "cache.inc"
 #include "edit.inc"
 #include "edl.inc"
-#include "file.inc"
+#include "file.h"
 #include "maxchannels.h"
 #include "mwindow.inc"
+#include "packagerenderer.inc"
 #include "playabletracks.inc"
 #include "playbackconfig.inc"
 #include "pluginserver.inc"
@@ -66,6 +67,15 @@ public:
        int audio_do;
 };
 
+class PackageFile : public File
+{
+public:
+       PackageFile(PackageRenderer *package_renderer);
+       ~PackageFile();
+       int write_frame_done(int64_t position);
+
+       PackageRenderer *package_renderer;
+};
 
 
 
@@ -131,7 +141,7 @@ public:
        int64_t audio_position;
        int64_t audio_preroll;
        int64_t audio_read_length;
-       File *file;
+       PackageFile *file;
 // This is 1 if an error is encountered.
        int result;
        VFrame ***video_output;
index 461272d2a028cebc755fcf1d9e05f076225b765a..fbb2f44939d13826e214a7e73973be6784def73a 100644 (file)
 #ifndef PACKAGERENDERER_INC
 #define PACKAGERENDERER_INC
 
-
-
-class PackageRenderer;
 class RenderPackage;
-
+class PackageFile;
+class PackageRenderer;
 
 #endif
index 381e1c0f4d925ce329b171c6c2d23ada7bd9c494..fb0339a95be3c9be82aaed956df8bbb1fc3fabce 100644 (file)
@@ -515,38 +515,20 @@ int PatchBay::update()
        return 0;
 }
 
-void PatchBay::synchronize_faders(float change, int data_type, Track *skip)
+void PatchBay::synchronize_faders(float dv, int data_type, Track *skip, int edge, int span)
 {
-       for(Track *current = mwindow->edl->tracks->first;
-               current;
-               current = NEXT)
-       {
-               if(current->data_type == data_type &&
-                       current->armed_gang(skip) &&
-                       current->is_armed() &&
-                       current != skip)
-               {
-                       FloatAutos *fade_autos = (FloatAutos*)current->automation->autos[AUTOMATION_FADE];
-                       double position = mwindow->edl->local_session->get_selectionstart(1);
-
-
-                       FloatAuto *keyframe = (FloatAuto*)fade_autos->get_auto_for_editing(position);
-
-                       float new_value = keyframe->get_value() + change;
-                       if(data_type == TRACK_AUDIO)
-                               CLAMP(new_value,
-                                     mwindow->edl->local_session->automation_mins[AUTOGROUPTYPE_AUDIO_FADE],
-                                     mwindow->edl->local_session->automation_maxs[AUTOGROUPTYPE_AUDIO_FADE]);
-                       else
-                               CLAMP(new_value,
-                                     mwindow->edl->local_session->automation_mins[AUTOGROUPTYPE_VIDEO_FADE],
-                                     mwindow->edl->local_session->automation_maxs[AUTOGROUPTYPE_VIDEO_FADE]);
-
-                       keyframe->set_value(new_value);
-
-                       PatchGUI *patch = get_patch_of(current);
-                       if(patch) patch->update(patch->x, patch->y);
-               }
+       for( Track *current=mwindow->edl->tracks->first; current; current=NEXT ) {
+               if( current == skip ) continue;
+               if( skip && !current->armed_gang(skip) ) continue;
+               if( current->data_type != data_type ) continue;
+               if( !current->is_armed() ) continue;
+               FloatAutos *fade_autos = (FloatAutos*)current->automation->autos[AUTOMATION_FADE];
+               double position = mwindow->edl->local_session->get_selectionstart(1);
+               FloatAuto *float_auto = (FloatAuto*)fade_autos->get_auto_for_editing(position);
+               int64_t pos = float_auto->position;
+               float_auto->bump_update(pos, dv, edge, span);
+               PatchGUI *patch = get_patch_of(current);
+               if( patch ) patch->update(patch->x, patch->y);
        }
 }
 
index 5d84e364781671e53e8a8e20e990c33fb50dcb1d..29096a7412283867e5abfc1ba63aba22c2b462da 100644 (file)
@@ -59,7 +59,7 @@ public:
        void update_meters(ArrayList<double> *module_levels);
        void stop_meters();
        void synchronize_nudge(int64_t value, Track *skip);
-       void synchronize_faders(float value, int data_type, Track *skip);
+       void synchronize_faders(float value, int data_type, Track *skip, int edge, int span);
        void set_meter_format(int mode, int min, int max);
        void reset_meters();
 
index f99601c1178f91db5306f1d3680d95efd986bf39..fa471477af7e1eb25338f6311be9e2374a252483 100644 (file)
@@ -71,6 +71,8 @@ PatchGUI::PatchGUI(MWindow *mwindow,
        change_source = 0;
        track_id = track ? track->get_id() : -1;
        mixer = 0;
+       edge = 0;
+       span = 1;
 }
 
 PatchGUI::~PatchGUI()
index edbfddedfb7d588d43f4547e314d971f8749bc14..980296a9d790ec222e12121a03c5602306915b7a 100644 (file)
 #include "guicast.h"
 #include "mwindow.inc"
 #include "patchbay.inc"
+#include "patchgui.inc"
 #include "intauto.inc"
 #include "track.inc"
 
 
-
-
-class TitlePatch;
-class PlayPatch;
-class RecordPatch;
-class AutoPatch;
-class GangPatch;
-class DrawPatch;
-class MutePatch;
-class ZoomPatch;
-class MasterPatch;
-class ExpandPatch;
-class NudgePatch;
-class MixPatch;
-
 class PatchGUI
 {
 public:
@@ -61,8 +47,7 @@ public:
                BC_Toggle *toggle,
                int *output);
        virtual int update(int x, int y);
-       virtual void synchronize_fade(float change) {};
-       void synchronize_faders(float change, int audio, int video);
+       void synchronize_faders(float change, int audio, int video, int edge, int span);
        char* calculate_nudge_text(int *changed);
        int64_t calculate_nudge(const char *string);
 
@@ -90,6 +75,7 @@ public:
        NudgePatch *nudge;
        MixPatch *mix;
        char string_return[BCTEXTLEN];
+       int edge, span;
 };
 
 
@@ -219,5 +205,4 @@ public:
        PatchGUI *patch;
 };
 
-
 #endif
index 26231a067dc584c13bec983c3f356db005488378..68eea315fa2772e2b539b8974a62ec0fab118921 100644 (file)
 #define PATCHGUI_INC
 
 class PatchGUI;
+class PlayPatch;
+class RecordPatch;
+class TitlePatch;
+class AutoPatch;
+class GangPatch;
+class DrawPatch;
+class MutePatch;
+class ZoomPatch;
+class MasterPatch;
+class ExpandPatch;
+class NudgePatch;
+class MixPatch;
 
 #endif
index 12a8fc950cfb5a0d1389d6d01516cabce78537f6..e13cb2f65f2d4b0a3523146d4822973758ae964c 100644 (file)
@@ -63,7 +63,6 @@ void PerformancePrefs::create_objects()
        char string[BCTEXTLEN];
        BC_Resources *resources = BC_WindowBase::get_resources();
        BC_WindowBase *win;
-       int maxw, curw;
 
        node_list = 0;
        generate_node_list();
@@ -73,38 +72,31 @@ void PerformancePrefs::create_objects()
 
        int y0 = y;
        win = add_subwindow(new BC_Title(x, y + ys5, _("Cache size (MB):"), MEDIUMFONT, resources->text_default));
-       maxw = win->get_w();
-       int x1 = x + xmargin4;
-       win = add_subwindow(new BC_Title(x1, y + ys5, _("Use HW Device:")));
-       x1 += win->get_w() + xs5;
-       PrefsUseHWDev *use_hw_dev = new PrefsUseHWDev(pwindow, this, x1, y);
-       use_hw_dev->create_objects();
-
+       int maxw = win->get_w();
        int y1 = y += ys30;
-       win = add_subwindow(new BC_Title(x, y + ys5, _("Seconds to preroll renders:")));
-       if((curw = win->get_w()) > maxw)
-               maxw = curw;
-       maxw += x + xs5;
-
-       cache_size = new CICacheSize(maxw, y0, pwindow, this);
+       win = add_subwindow(new BC_Title(x, y1 + ys5, _("Seconds to preroll renders:")));
+       maxw = bmax(win->get_w(), maxw);
+       int x2 = x + maxw + xs5;
+       int y2 = y += ys30;
+       cache_size = new CICacheSize(x2, y0, pwindow, this);
        cache_size->create_objects();
-
-       add_subwindow(new BC_Title(x, y + ys5, _("Seconds to preroll renders:")));
-       PrefsRenderPreroll *preroll = new PrefsRenderPreroll(pwindow, this, maxw, y1);
+       PrefsRenderPreroll *preroll = new PrefsRenderPreroll(pwindow, this, x2, y1);
        preroll->create_objects();
+       add_subwindow(new PrefsForceUniprocessor(pwindow, x, y2));
        y += ys30;
 
-       x1 = x + xmargin4;
-       BC_Title *smp_title = new BC_Title(x1, y + ys5, _("Project SMP cpus:"));
-       add_subwindow(smp_title);
-       x1 += smp_title->get_w() + xs5;
-       PrefsProjectSMP *proj_smp = new PrefsProjectSMP(pwindow, this, x1, y);
+       int x1 = x + xmargin4;
+       add_subwindow(cache_transitions = new CacheTransitions(x1, y0, pwindow, this));
+       win = add_subwindow(new BC_Title(x1, y1, _("Use HW Device:")));
+       maxw = win->get_w();
+       win = add_subwindow(new BC_Title(x1, y2, _("Project SMP cpus:")));
+       maxw = bmax(win->get_w(), maxw);
+       x2 = x1 + maxw + xs5;
+       PrefsUseHWDev *use_hw_dev = new PrefsUseHWDev(pwindow, this, x2, y1);
+       use_hw_dev->create_objects();
+       PrefsProjectSMP *proj_smp = new PrefsProjectSMP(pwindow, this, x2, y2);
        proj_smp->create_objects();
 
-       PrefsForceUniprocessor *force_1cpu = new PrefsForceUniprocessor(pwindow, x, y);
-       add_subwindow(force_1cpu);
-       y += ys30;
-
 // Background rendering
        add_subwindow(new BC_Bar(xs5, y, get_w() - xs10));
        y += ys5;
@@ -322,6 +314,20 @@ int CICacheSize::handle_event()
        return 0;
 }
 
+CacheTransitions::CacheTransitions(int x, int y,
+       PreferencesWindow *pwindow, PerformancePrefs *subwindow)
+ : BC_CheckBox(x, y, pwindow->thread->preferences->cache_transitions,
+       _("Cache Transitions"))
+{
+       this->pwindow = pwindow;
+}
+
+int CacheTransitions::handle_event()
+{
+       pwindow->thread->preferences->cache_transitions = get_value();
+       return 0;
+}
+
 
 PrefsUseHWDev::PrefsUseHWDev(PreferencesWindow *pwindow,
                PerformancePrefs *subwindow, int x, int y)
index e9acd3c70f8c9212170ec900c36ceb078209ee3f..6d15a416380313428e3c7dcb224f28163577095c 100644 (file)
@@ -46,6 +46,7 @@ public:
        int hot_node;
 
        CICacheSize *cache_size;
+       CacheTransitions *cache_transitions;
        PerfsUseHWDev *use_hw_dev;
 
        enum
@@ -338,6 +339,18 @@ public:
        PreferencesWindow *pwindow;
 };
 
+class CacheTransitions : public BC_CheckBox
+{
+public:
+       CacheTransitions(int x, int y,
+               PreferencesWindow *pwindow,
+               PerformancePrefs *subwindow);
+
+       int handle_event();
+
+       PreferencesWindow *pwindow;
+};
+
 class PrefsUseHWDevItems : public ArrayList<BC_ListBoxItem *>
 {
 public:
index f034704c535b17178a8d283270f5a2ecc59142d9..d69da52a29c9d7caa44da6dabe819f3a76b8d727 100644 (file)
@@ -44,6 +44,7 @@ class PrefsRenderFarmSortNodes;
 class PrefsRenderFarmReset;
 class PrefsRenderFarmWatchdog;
 class CICacheSize;
+class CacheTransitions;
 class PerfsUseHWDev;
 
 #endif
index 82bd7bb6587b930b77caa7f4da7673255539b3a3..3b2b9ed4313f2ac01699179015e7fd61a85c9bf4 100644 (file)
@@ -71,6 +71,7 @@ PlaybackEngine::PlaybackEngine(MWindow *mwindow, Canvas *output)
        tracking_done = new Condition(1, "PlaybackEngine::tracking_done");
        pause_lock = new Condition(0, "PlaybackEngine::pause_lock");
        start_lock = new Condition(0, "PlaybackEngine::start_lock");
+       cache_lock = new Mutex("PlaybackEngine::cache_lock");
        input_lock = new Condition(1, "PlaybackEngine::input_lock");
        output_lock = new Condition(0, "PlaybackEngine::output_lock", 1);
 
@@ -83,8 +84,8 @@ PlaybackEngine::~PlaybackEngine()
        done = 1;
        output_lock->unlock();
        Thread::join();
-       delete preferences;
        delete_render_engine();
+       delete preferences;
        if( audio_cache )
                audio_cache->remove_user();
        if( video_cache )
@@ -93,6 +94,7 @@ PlaybackEngine::~PlaybackEngine()
        delete tracking_done;
        delete pause_lock;
        delete start_lock;
+       delete cache_lock;
        delete renderengine_lock;
        delete command;
        delete next_command;
@@ -145,14 +147,18 @@ void PlaybackEngine::delete_render_engine()
 
 void PlaybackEngine::arm_render_engine()
 {
+       renderengine_lock->lock("PlaybackEngine::arm_render_engine");
        if( render_engine )
                render_engine->arm_command(command);
+       renderengine_lock->unlock();
 }
 
 void PlaybackEngine::start_render_engine()
 {
+       renderengine_lock->lock("PlaybackEngine::start_render_engine");
        if( render_engine )
                render_engine->start_command();
+       renderengine_lock->unlock();
 }
 
 void PlaybackEngine::wait_render_engine()
@@ -164,26 +170,35 @@ void PlaybackEngine::wait_render_engine()
 
 void PlaybackEngine::create_cache()
 {
+       cache_lock->lock("PlaybackEngine::create_cache");
        if( audio_cache )
                audio_cache->remove_user();
        if( video_cache )
                video_cache->remove_user();
        audio_cache = new CICache(preferences);
        video_cache = new CICache(preferences);
+       cache_lock->unlock();
 }
 
 
 void PlaybackEngine::perform_change()
 {
        switch( command->change_type ) {
-               case CHANGE_ALL:
-                       create_cache();
-               case CHANGE_EDL:
-                       create_render_engine();
-                       break;
-               case CHANGE_PARAMS:
-                       render_engine->get_edl()->synchronize_params(command->get_edl());
-               case CHANGE_NONE:
+       case CHANGE_ALL:
+               create_cache();
+       case CHANGE_EDL:
+               create_render_engine();
+               break;
+       case CHANGE_PARAMS: {
+               renderengine_lock->lock("PlaybackEngine::perform_change");
+               EDL *edl = render_engine ? render_engine->get_edl() : 0;
+               if( edl ) edl->add_user();
+               renderengine_lock->unlock();
+               if( !edl ) break;
+               edl->synchronize_params(command->get_edl());
+               edl->remove_user();
+               }
+       case CHANGE_NONE:
                        break;
        }
 }
@@ -462,6 +477,12 @@ int PlaybackEngine::get_direction()
        return TransportCommand::get_direction(curr_command);
 }
 
+void PlaybackEngine::update_preferences(Preferences *prefs)
+{
+       preferences->copy_from(prefs);
+       create_render_engine();
+}
+
 void PlaybackEngine::send_command(int command, EDL *edl, int wait_tracking, int use_inout)
 {
 //printf("PlaybackEngine::send_command 1 %d\n", command);
index ee27ff19a4b55e4ddf1db4250d7655c2f8ddc02f..9fdb45fbc428fd5b7b8d35be2b5ebee141b33d55 100644 (file)
@@ -86,6 +86,7 @@ public:
        void stop_playback(int wait);
        void refresh_frame(int change_type, EDL *edl, int dir=1);
        int get_direction();
+       void update_preferences(Preferences *prefs);
 
 // Maintain caches through console changes
        CICache *audio_cache, *video_cache;
@@ -106,6 +107,8 @@ public:
        Condition *pause_lock;
 // Wait until thread has started
        Condition *start_lock;
+// Reinit caches
+       Mutex *cache_lock;
 
        MWindow *mwindow;
        Canvas *output;
index 94a208844658668db4048770b28b1eefb3044843..29306b8c5f50e222ba2dce26e973319c6bd895ea 100644 (file)
@@ -939,8 +939,7 @@ double PluginClient::get_project_framerate()
 
 const char *PluginClient::get_source_path()
 {
-       EDL *edl = get_edl();
-       Plugin *plugin = edl->tracks->plugin_exists(server->plugin_id);
+       Plugin *plugin = server->edl->tracks->plugin_exists(server->plugin_id);
        int64_t source_position = plugin->startproject;
        Edit *edit = plugin->track->edits->editof(source_position,PLAY_FORWARD,0);
        Indexable *indexable = edit ? edit->get_source() : 0;
index 486d73195d0c4605f055638f1aab9ec7adfa24f1..a0756e73ab630dec12a803e6e8a22432f1c0fe21 100644 (file)
@@ -889,7 +889,7 @@ int PluginFVClient::activate(int width, int height, int color_model)
                char args[BCTEXTLEN];
                snprintf(args, sizeof(args),
                        "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
-                       width, height, pix_fmt, best_rate.num, best_rate.den, aspect_w, aspect_h);
+                       width, height, pix_fmt, best_rate.den, best_rate.num, aspect_w, aspect_h);
                ret = avfilter_graph_create_filter(&fsrc, avfilter_get_by_name("buffer"),
                        "in", args, NULL, graph);
        }
@@ -947,7 +947,7 @@ int PluginFAClient::process_buffer(int64_t size, Samples **buffer, int64_t start
                frame->format = AV_SAMPLE_FMT_FLTP;
                frame->channel_layout = (1<<in_channels)-1;
                frame->sample_rate = sample_rate;
-               frame->pts = local_to_edl(filter_position);
+               frame->pts = filter_position;
        }
 
        int retry = 10;
@@ -1048,11 +1048,11 @@ int PluginFVClient::process_buffer(VFrame **frames, int64_t position, double fra
                ret = av_buffersink_get_frame(fsink, frame);
                if( ret >= 0 || ret != AVERROR(EAGAIN) ) break;
                if( !fsrc ) { ret = AVERROR(EIO);  break; }
-               read_frame(vframe, 0, filter_position++, frame_rate, 0);
+               read_frame(vframe, 0, filter_position, frame_rate, 0);
                frame->format = pix_fmt;
                frame->width  = width;
                frame->height = height;
-               frame->pts = local_to_edl(position);
+               frame->pts = filter_position++;
                ret = av_frame_get_buffer(frame, 32);
                if( ret < 0 ) break;
                ret = transfer_pixfmt(vframe, frame);
index f783fbfc8998eb60c2b513e89b1f2838861f6f55..9800fceec14100454dca4b53eb2fe72522c4ef4f 100644 (file)
@@ -59,6 +59,7 @@ Preferences::Preferences()
        if( strlen(index_directory) )
                fs.complete_path(index_directory);
        cache_size = 0x10000000;
+       cache_transitions = 1;
        index_size = 0x400000;
        index_count = 500;
        use_thumbnails = 1;
@@ -206,6 +207,7 @@ void Preferences::copy_from(Preferences *that)
        for( int i=0; i<that->file_probes.size(); ++i )
                this->file_probes.append(new ProbePref(*that->file_probes[i]));
        cache_size = that->cache_size;
+       cache_transitions = that->cache_transitions;
        project_smp = that->project_smp;
        force_uniprocessor = that->force_uniprocessor;
        strcpy(lv2_path, that->lv2_path);
@@ -387,6 +389,7 @@ int Preferences::load_defaults(BC_Hash *defaults)
        use_brender = defaults->get("USE_BRENDER", use_brender);
        brender_fragment = defaults->get("BRENDER_FRAGMENT", brender_fragment);
        cache_size = defaults->get("CACHE_SIZE", cache_size);
+       cache_transitions = defaults->get("CACHE_TRANSITIONS", cache_transitions);
        local_rate = defaults->get("LOCAL_RATE", local_rate);
        use_renderfarm = defaults->get("USE_RENDERFARM", use_renderfarm);
        renderfarm_port = defaults->get("RENDERFARM_PORT", renderfarm_port);
@@ -485,6 +488,7 @@ int Preferences::save_defaults(BC_Hash *defaults)
        defaults->update("ANDROID_PORT", android_port);
 
        defaults->update("CACHE_SIZE", cache_size);
+       defaults->update("CACHE_TRANSITIONS", cache_transitions);
        defaults->update("INDEX_DIRECTORY", index_directory);
        defaults->update("INDEX_SIZE", index_size);
        defaults->update("INDEX_COUNT", index_count);
index dc6589819dd54af5dd9837b6560a9495fd650dde..4b60577ab9f2b7dab56422b3a831b1ee6d2b2e1b 100644 (file)
@@ -156,6 +156,7 @@ public:
 // Several caches of cache_size exist so multiply by 4.
 // rendering, playback, timeline, preview
        int64_t cache_size;
+       int cache_transitions;
 
        int use_renderfarm;
        int renderfarm_port;
index 52de4f5526a2888d8e8dd2341c709916f2c40339..75d8fe81e5741296b0fdc7c1ee31c4015b09ff55 100644 (file)
@@ -124,6 +124,7 @@ BC_Window* PreferencesThread::new_gui()
        redraw_overlays = 0;
        close_assets = 0;
        reload_plugins = 0;
+       reset_caches = 0;
        //int need_new_indexes = 0;
        rerender = 0;
 
@@ -251,6 +252,9 @@ int PreferencesThread::apply_settings()
                File::setenv_path("LV2_PATH", preferences->lv2_path, 1);
                mwindow->restart_status = -1;
        }
+       if( preferences->cache_size != mwindow->preferences->cache_size ||
+           preferences->cache_transitions != mwindow->preferences->cache_transitions )
+               reset_caches = 1;
 
        if( mwindow->preferences->perpetual_session && !preferences->perpetual_session )
                mwindow->remove_undo_data();
@@ -269,12 +273,16 @@ int PreferencesThread::apply_settings()
        else {
                BC_Trace::disable_locks();
        }
+       if( reset_caches )
+               mwindow->reset_caches(0);
 
        mwindow->reset_android_remote();
        int ffmpeg_early_probe = mwindow->preferences->get_file_probe_armed("FFMPEG_Early");
+       mwindow->gui->lock_window("PreferencesThread::apply_settings 6");
        mwindow->gui->ffmpeg_toggle->update(ffmpeg_early_probe);
        mwindow->gui->ffmpeg_toggle->set_tooltip(ffmpeg_early_probe ?
                FFMPEG_EARLY_TIP : FFMPEG_LATE_TIP);
+       mwindow->gui->unlock_window();
        mwindow->gui->mainshbtns->load(mwindow->preferences);
        mwindow->init_brender();
 
index 5309b22adcc1bc7ee49a60fe90107efe9373d9d8..653199b6bf7762af70b31192bf20e77742cdbbb7 100644 (file)
@@ -71,6 +71,7 @@ public:
        int rerender;
        int close_assets;
        int reload_plugins;
+       int reset_caches;
        PreferencesWindow *window;
        MWindow *mwindow;
 // Copy of mwindow preferences
index 1391351cccec3f38ad42a31b4952762ba8175119..f5ca9f966748a3249f3f6d1c746b9e3b1c47e58f 100644 (file)
 enum
 {
        RENDERFARM_NONE,
-       RENDERFARM_PREFERENCES,  // Get preferences on startup
+       RENDERFARM_PREFERENCES,  // Get preferences on startup
        RENDERFARM_ASSET,        // Get output format on startup
        RENDERFARM_EDL,          // Get EDL on startup
        RENDERFARM_PACKAGE,      // Get one package after another to render
@@ -135,7 +135,7 @@ enum
        RENDERFARM_SET_RESULT,   // Update error status
        RENDERFARM_GET_RESULT,   // Retrieve error status
        RENDERFARM_DONE,         // Quit
-       RENDERFARM_SET_VMAP,     // Update video map in background rendering
+       RENDERFARM_SET_VMAP,     // Update video map in background rendering
        RENDERFARM_COMMAND,      // Get the client to run
        RENDERFARM_TUNER,        // Run a tuner server
        RENDERFARM_PACKAGES,     // Run packages
index 17b345112a4c49891650d459fbe3fe0a51c541bf..807b866afd2c9c96b09924ebe01decc99c43f2e5 100644 (file)
@@ -122,6 +122,11 @@ void RenderFarmClient::main_loop()
                        perror(_("RenderFarmClient::main_loop: socket"));
                        return;
                }
+               struct linger lgr;
+               lgr.l_onoff = 0;
+               lgr.l_linger = 0;
+               if( setsockopt(socket_fd, SOL_SOCKET, SO_LINGER, &lgr, sizeof(lgr)) < 0 )
+                       perror("RenderFarmClient::setsockopt:setlinger 0");
 
                if(bind(socket_fd,
                        (struct sockaddr*)&addr,
@@ -147,6 +152,11 @@ void RenderFarmClient::main_loop()
                        perror(_("RenderFarmClient::main_loop: socket"));
                        return;
                }
+               struct linger lgr;
+               lgr.l_onoff = 0;
+               lgr.l_linger = 0;
+               if( setsockopt(socket_fd, SOL_SOCKET, SO_LINGER, &lgr, sizeof(lgr)) < 0 )
+                       perror("RenderFarmClient::setsockopt:setlinger 1");
 
                if(bind(socket_fd,
                        (struct sockaddr*)&addr,
@@ -267,7 +277,8 @@ int RenderFarmClientThread::read_socket(char *data, int len)
        int bytes_read = 0;
        int offset = 0;
 //printf("RenderFarmClientThread::read_socket 1\n");
-       watchdog->begin_request();
+       if( watchdog )
+               watchdog->begin_request();
        while(len > 0 && bytes_read >= 0)
        {
                bytes_read = read(socket_fd, data + offset, len);
@@ -282,7 +293,8 @@ int RenderFarmClientThread::read_socket(char *data, int len)
                        break;
                }
        }
-       watchdog->end_request();
+       if( watchdog )
+               watchdog->end_request();
 //printf("RenderFarmClientThread::read_socket 10\n");
 
        return offset;
index a40fcac2aa7d53cb7a7b5b076fe4b637f0bb99b9..a551c28b4c68ecea7d953ce2ddad1fb4669a118a 100644 (file)
@@ -253,3 +253,21 @@ void SaveProject::run()
        mwindow->save_project(dir_path, save_mode, overwrite, reload);
 }
 
+  
+SaveSession::SaveSession(MWindow *mwindow)
+ : BC_MenuItem(_("Save Session"),_("Ctrl-s"),'s')
+{
+       this->mwindow = mwindow;
+       set_ctrl(1);
+}
+
+int SaveSession::handle_event()
+{
+       mwindow->save_defaults();
+       mwindow->save_backup();
+       mwindow->save(0);
+       mwindow->gui->show_message(_("Saved session."));
+       return 1;
+}
+
+
index 15a1ec71cffc9988626dfa50d9fc3f0faf390b31..cbf0c94a30f13116a03ca2786b99007fbaa85f22 100644 (file)
@@ -129,4 +129,12 @@ public:
        MWindow *mwindow;
 };
 
+class SaveSession : public BC_MenuItem
+{
+public:
+       SaveSession(MWindow *mwindow);
+       int handle_event();
+       MWindow *mwindow;
+};
+
 #endif
index 1cf0f69dbcd6a51c14251977759d64ca3445a189..f97ef3c28e1a82c2b2b3be67e7984fab6014dfb6 100644 (file)
@@ -250,24 +250,18 @@ double Track::get_length()
 int Track::has_speed()
 {
        FloatAutos *autos = (FloatAutos*)automation->autos[AUTOMATION_SPEED];
-       if(autos)
-       {
-               if(autos->first)
-               {
-                       for(FloatAuto *current = (FloatAuto*)autos->first;
-                               current;
-                               current = (FloatAuto*)current->next)
-                       {
-                               if(!EQUIV(current->get_value(), 1.0) ||
-                                       !EQUIV(current->get_control_in_value(), 0.0) ||
-                                       !EQUIV(current->get_control_out_value(), 0.0))
-                               {
-                                       return 1;
-                               }
-                       }
+       if( autos ) {
+               FloatAuto *current = (FloatAuto*)autos->first;
+               for( ; current; current=(FloatAuto*)current->next ) {
+                       if( !EQUIV(current->get_value(0), 1.0) ||
+                           !EQUIV(current->get_control_in_value(), 0.0) ||
+                           !EQUIV(current->get_control_out_value(), 0.0))
+                               return 1;
+                       if( current->curve_mode == FloatAuto::BUMP &&
+                           !EQUIV(current->get_value(1), 1.0) )
+                               return 1;
                }
        }
-
        return 0;
 }
 
@@ -872,18 +866,16 @@ int Track::copy_automation(double selectionstart,
        return 0;
 }
 
-int Track::paste_automation(double selectionstart, double total_length,
-       double frame_rate, int64_t sample_rate,
-       FileXML *file, int default_only, int active_only)
+int Track::paste_automation(FileXML *file,
+       double selectionstart, double src_length, double src_rate,
+       int default_only, int active_only)
 {
 // Only used for pasting automation alone.
-       double scale = data_type == TRACK_AUDIO ?
-               edl->session->sample_rate / sample_rate :
-               edl->session->frame_rate / frame_rate ;
-
-       total_length *= scale;
-       int64_t start = to_units(selectionstart, 0);
-       int64_t length = to_units(total_length, 1);
+       double dst_rate = data_type == TRACK_AUDIO ?
+               edl->session->sample_rate : edl->session->frame_rate;
+       double scale = dst_rate / src_rate;
+       int64_t start = to_units(selectionstart, 1);
+       int64_t length = to_units(selectionstart + src_length, 1) - start;
        int result = 0;
        int current_pluginset = 0;
 //printf("Track::paste_automation 1\n");
@@ -1798,6 +1790,19 @@ void Track::set_camera(float x, float y, float z)
        set_fauto_xyz(AUTOMATION_CAMERA_X, x, y, z);
 }
 
+int Track::is_hidden()
+{
+       if( master ) return 0;
+       if( edl->session->gang_tracks == GANG_MEDIA ) return 1;
+       if( edl->session->gang_tracks == GANG_CHANNELS ) {
+               for( Track *track=previous; track; track=track->previous ) {
+                       if( track->data_type == data_type ) return 1;
+                       if( track->master ) return 0;
+               }
+       }
+       return 0;
+}
+
 Track *Track::gang_master()
 {
        Track *track = this;
@@ -1810,7 +1815,6 @@ Track *Track::gang_master()
                while( current && !track->master ) {
                        if( !(current = current->previous) ) break;
                        if( current->data_type == data_type ) track = current;
-                       if( track->master ) break;
                }
                break; }
        case GANG_MEDIA: {
@@ -1821,18 +1825,15 @@ Track *Track::gang_master()
        return track;
 }
 
-int Track::is_hidden()
+int Track::in_gang(Track *track)
 {
-       if( master ) return 0;
-       if( edl->session->gang_tracks == GANG_MEDIA ) return 1;
-       if( edl->session->gang_tracks == GANG_CHANNELS ) {
-               for( Track *track=previous; track; track=track->previous ) {
-                       if( track->data_type == data_type ) return 1;
-                       if( track->master ) return 0;
-               }
-       }
-       return 0;
+       if( edl->session->gang_tracks == GANG_NONE ) return ganged;
+       Track *current = this;
+       while( current && !current->master ) current = current->previous;
+       while( track && !track->master ) track = track->previous;
+       return current == track ? 1 : 0;
 }
+
 int Track::is_armed()
 {
        return gang_master()->armed;
@@ -1864,3 +1865,15 @@ int Track::index_in(Mixer *mixer)
        return k;
 }
 
+void Track::create_keyframes(double position, int mask, int mode)
+{
+       for( int idx=0; idx<AUTOMATION_TOTAL; mask>>=1,++idx ) {
+               if( !(mask & 1) ) continue;
+               Autos *autos = automation->autos[idx];
+               if( !autos ) continue;
+               FloatAuto *float_auto = (FloatAuto *)
+                       autos->get_auto_for_editing(position, -1);
+               float_auto->change_curve_mode((FloatAuto::t_mode)mode, 0);
+       }
+}
+
index 32c6a8ec689e41a2bd25a8c6e129d129eeffcf69..9c12af1fff1fc31537f2cf558bc1ab140acae321 100644 (file)
@@ -171,6 +171,7 @@ public:
        Plugin *plugin_exists(int plugin_id);
        Track *gang_master();
        int is_hidden();
+       int in_gang(Track *track);
        int is_armed();
        int is_ganged();
        int armed_gang(Track *track);
@@ -244,8 +245,8 @@ public:
        virtual int copy_automation_derived(AutoConf *auto_conf,
                double selectionstart, double selectionend,
                FileXML *file) { return 0; };
-       int paste_automation(double selectionstart, double total_length,
-               double frame_rate, int64_t sample_rate, FileXML *file,
+       int paste_automation(FileXML *file,
+               double selectionstart, double src_length, double src_rate,
                int default_only, int active_only);
        virtual int paste_automation_derived(double selectionstart, double selectionend,
                double total_length, FileXML *file, int shift_autos, int &current_pan) { return 0; };
@@ -321,6 +322,7 @@ public:
 // If the edit under position is playable.
 // Used by PlayableTracks::is_playable.
        int playable_edit(int64_t position, int direction);
+       void create_keyframes(double position, int mask, int mode);
 
 // ===================================== for handles, titles, etc
 
index 40d87c9cba68013db58a48cef0ea2f2b8b15c4f0..c0fea44a35d82970fa662baf7f558a5e07a00a24 100644 (file)
@@ -1658,6 +1658,9 @@ void TrackCanvas::draw_highlighting()
                        }
                        break;
 
+               case DRAG_SPEED:
+                       draw_speed_highlight();
+                       break;
        }
 
        if( draw_box )
@@ -1666,6 +1669,33 @@ void TrackCanvas::draw_highlighting()
        draw_selected_edits(mwindow->edl, 0, 0, GREEN+BLUE, RED);
 }
 
+void TrackCanvas::draw_speed_highlight()