mixer
authorGood Guy <good1.2guy@gmail.com>
Mon, 6 Nov 2017 02:41:33 +0000 (19:41 -0700)
committerGood Guy <good1.2guy@gmail.com>
Mon, 6 Nov 2017 02:41:33 +0000 (19:41 -0700)
59 files changed:
cinelerra-5.1/cinelerra/Makefile
cinelerra-5.1/cinelerra/aedit.C
cinelerra-5.1/cinelerra/apatchgui.C
cinelerra-5.1/cinelerra/apatchgui.h
cinelerra-5.1/cinelerra/assetpopup.C
cinelerra-5.1/cinelerra/assetpopup.h
cinelerra-5.1/cinelerra/assetpopup.inc
cinelerra-5.1/cinelerra/cwindow.C
cinelerra-5.1/cinelerra/cwindowgui.C
cinelerra-5.1/cinelerra/edl.C
cinelerra-5.1/cinelerra/edl.h
cinelerra-5.1/cinelerra/gwindowgui.C
cinelerra-5.1/cinelerra/keyframepopup.C
cinelerra-5.1/cinelerra/keyframepopup.h
cinelerra-5.1/cinelerra/mainmenu.C
cinelerra-5.1/cinelerra/mainmenu.h
cinelerra-5.1/cinelerra/mainsession.C
cinelerra-5.1/cinelerra/mainsession.h
cinelerra-5.1/cinelerra/menueffects.C
cinelerra-5.1/cinelerra/mwindow.C
cinelerra-5.1/cinelerra/mwindow.h
cinelerra-5.1/cinelerra/mwindow.inc
cinelerra-5.1/cinelerra/mwindowedit.C
cinelerra-5.1/cinelerra/mwindowgui.C
cinelerra-5.1/cinelerra/mwindowgui.h
cinelerra-5.1/cinelerra/patchgui.C
cinelerra-5.1/cinelerra/patchgui.h
cinelerra-5.1/cinelerra/playbackengine.C
cinelerra-5.1/cinelerra/playbackengine.h
cinelerra-5.1/cinelerra/playtransport.C
cinelerra-5.1/cinelerra/playtransport.h
cinelerra-5.1/cinelerra/renderengine.C
cinelerra-5.1/cinelerra/savefile.C
cinelerra-5.1/cinelerra/theme.C
cinelerra-5.1/cinelerra/timebar.C
cinelerra-5.1/cinelerra/track.C
cinelerra-5.1/cinelerra/track.h
cinelerra-5.1/cinelerra/tracking.C
cinelerra-5.1/cinelerra/tracks.C
cinelerra-5.1/cinelerra/transportque.C
cinelerra-5.1/cinelerra/vedit.C
cinelerra-5.1/cinelerra/vmodule.C
cinelerra-5.1/cinelerra/vpatchgui.C
cinelerra-5.1/cinelerra/vpatchgui.h
cinelerra-5.1/cinelerra/vwindowgui.C
cinelerra-5.1/cinelerra/vwindowgui.h
cinelerra-5.1/cinelerra/zwindow.C [new file with mode: 0644]
cinelerra-5.1/cinelerra/zwindow.h [new file with mode: 0644]
cinelerra-5.1/cinelerra/zwindow.inc [new file with mode: 0644]
cinelerra-5.1/cinelerra/zwindowgui.C [new file with mode: 0644]
cinelerra-5.1/cinelerra/zwindowgui.h [new file with mode: 0644]
cinelerra-5.1/cinelerra/zwindowgui.inc [new file with mode: 0644]
cinelerra-5.1/guicast/bcwindowbase.C
cinelerra-5.1/picon/cinfinity/mixpatch.png [new file with mode: 0644]
cinelerra-5.1/picon/cinfinity/mixpatch_checked.png [new file with mode: 0644]
cinelerra-5.1/picon/cinfinity/mixpatch_checkedhi.png [new file with mode: 0644]
cinelerra-5.1/picon/cinfinity/mixpatch_dn.png [new file with mode: 0644]
cinelerra-5.1/picon/cinfinity/mixpatch_hi.png [new file with mode: 0644]
cinelerra-5.1/picon/cinfinity/mixpatch_up.png [new file with mode: 0644]

index fa22ff0ceebffb7c715469018bac51335bf761fb..d6895838393e1a8d95f6e56a78baec3b1d8f0e6b 100644 (file)
@@ -333,6 +333,8 @@ OBJS = \
        $(OBJDIR)/wwindow.o \
        $(OBJDIR)/zoombar.o \
        $(OBJDIR)/zoompanel.o \
+       $(OBJDIR)/zwindow.o \
+       $(OBJDIR)/zwindowgui.o \
 
 #      $(OBJDIR)/renderfarmfsclient.o \
 #      $(OBJDIR)/renderfarmfsserver.o \
index b6aa0268365ad18d3266a0783a8d84e1800daf7d..3b830bb0dde8ccb17b96d8b2e9080ee260c84454 100644 (file)
@@ -71,7 +71,7 @@ int64_t AEdit::get_source_end(int64_t default_)
 
        if(nested_edl)
        {
-               return (int64_t)(nested_edl->tracks->total_playable_length() *
+               return (int64_t)(nested_edl->tracks->total_length() *
                        edl->session->sample_rate + 0.5);
        }
 
index 64d458f5127c99761dfcce2e71007ab6c57326a9..824e7a868db5cf7f6f2a7322692186212405c972 100644 (file)
@@ -32,6 +32,7 @@
 #include "intautos.h"
 #include "language.h"
 #include "localsession.h"
+#include "mainsession.h"
 #include "mainundo.h"
 #include "mwindow.h"
 #include "mwindowgui.h"
 #include "patchbay.h"
 #include "theme.h"
 #include "trackcanvas.h"
+#include "zwindow.h"
 
-
-
-
-APatchGUI::APatchGUI(MWindow *mwindow,
-       PatchBay *patchbay,
-       ATrack *track,
-       int x,
-       int y)
- : PatchGUI(mwindow,
-       patchbay,
-       track,
-       x,
-       y)
+APatchGUI::APatchGUI(MWindow *mwindow, PatchBay *patchbay,
+               ATrack *track, int x, int y)
+ : PatchGUI(mwindow, patchbay, track, x, y)
 {
        data_type = TRACK_AUDIO;
        this->atrack = track;
@@ -64,9 +56,9 @@ APatchGUI::APatchGUI(MWindow *mwindow,
 
 APatchGUI::~APatchGUI()
 {
-       if(fade) delete fade;
-       if(meter) delete meter;
-       if(pan) delete pan;
+       if( fade ) delete fade;
+       if( meter ) delete meter;
+       if( pan ) delete pan;
 }
 
 void APatchGUI::create_objects()
@@ -78,23 +70,20 @@ int APatchGUI::reposition(int x, int y)
 {
        int y1 = PatchGUI::reposition(x, y);
 
-       if(fade) fade->reposition_window(fade->get_x(),
-               y1 + y);
+       if( fade )
+               fade->reposition_window(fade->get_x(), y1+y);
        y1 += mwindow->theme->fade_h;
-
-       if(meter) meter->reposition_window(meter->get_x(),
-               y1 + y,
-               -1,
-               meter->get_w());
+       if( meter )
+               meter->reposition_window(meter->get_x(), y1+y, -1, meter->get_w());
        y1 += mwindow->theme->meter_h;
-
-       if(pan) pan->reposition_window(pan->get_x(),
-               y1 + y);
-
-       if(nudge) nudge->reposition_window(nudge->get_x(),
-               y1 + y);
-
+       if( mix )
+               mix->reposition_window(mix->get_x(), y1+y);
+       if( pan )
+               pan->reposition_window(pan->get_x(), y1+y);
+       if( nudge )
+               nudge->reposition_window(nudge->get_x(), y1+y);
        y1 += mwindow->theme->pan_h;
+
        return y1;
 }
 
@@ -104,109 +93,78 @@ int APatchGUI::update(int x, int y)
        int x1 = 0;
        int y1 = PatchGUI::update(x, y);
 
-       if(fade)
-       {
-               if(h - y1 < mwindow->theme->fade_h)
-               {
+       if( fade ) {
+               if( h - y1 < mwindow->theme->fade_h ) {
                        delete fade;
                        fade = 0;
                }
-               else
-               {
+               else {
                        FloatAuto *previous = 0, *next = 0;
                        double unit_position = mwindow->edl->local_session->get_selectionstart(1);
                        unit_position = mwindow->edl->align_to_frame(unit_position, 0);
                        unit_position = atrack->to_units(unit_position, 0);
                        FloatAutos *ptr = (FloatAutos*)atrack->automation->autos[AUTOMATION_FADE];
-                       float value = ptr->get_value(
-                               (long)unit_position,
-                               PLAY_FORWARD,
-                               previous,
-                               next);
-                       fade->update(fade->get_w(),
-                                    value,
+                       float value = ptr->get_value((long)unit_position, PLAY_FORWARD, previous, next);
+                       fade->update(fade->get_w(), value,
                                     mwindow->edl->local_session->automation_mins[AUTOGROUPTYPE_AUDIO_FADE],
                                     mwindow->edl->local_session->automation_maxs[AUTOGROUPTYPE_AUDIO_FADE]);
                }
        }
        else
-       if(h - y1 >= mwindow->theme->fade_h)
-       {
-               patchbay->add_subwindow(fade = new AFadePatch(mwindow,
-                       this,
-                       x1 + x,
-                       y1 + y,
+       if( h - y1 >= mwindow->theme->fade_h ) {
+               patchbay->add_subwindow(fade = new AFadePatch(mwindow, this, x1+x, y1+y,
                        patchbay->get_w() - 10));
        }
        y1 += mwindow->theme->fade_h;
 
-       if(meter)
-       {
-               if(h - y1 < mwindow->theme->meter_h)
-               {
-                       delete meter;
-                       meter = 0;
+       if( meter ) {
+               if( h - y1 < mwindow->theme->meter_h ) {
+                       delete meter;  meter = 0;
                }
        }
        else
-       if(h - y1 >= mwindow->theme->meter_h)
-       {
-               patchbay->add_subwindow(meter = new AMeterPatch(mwindow,
-                       this,
-                       x1 + x,
-                       y1 + y));
+       if( h - y1 >= mwindow->theme->meter_h ) {
+               patchbay->add_subwindow(meter = new AMeterPatch(mwindow, this, x1+x, y1+y));
        }
        y1 += mwindow->theme->meter_h;
-       x1 += 10;
-
-       if(pan)
-       {
-               if(h - y1 < mwindow->theme->pan_h)
-               {
-                       delete pan;
-                       pan = 0;
-                       delete nudge;
-                       nudge = 0;
+
+       if( pan ) {
+               if( h - y1 < mwindow->theme->pan_h ) {
+                       delete mix;    mix = 0;
+                       delete pan;    pan = 0;
+                       delete nudge;  nudge = 0;
                }
-               else
-               {
-                       if(pan->get_total_values() != mwindow->edl->session->audio_channels)
-                       {
+               else {
+                       if( mwindow->session->selected_zwindow >= 0 ) {
+                               int v = mwindow->mixer_track_active(track);
+                               mix->update(v);
+                       }
+                       if( pan->get_total_values() != mwindow->edl->session->audio_channels ) {
                                pan->change_channels(mwindow->edl->session->audio_channels,
                                        mwindow->edl->session->achannel_positions);
                        }
-                       else
-                       {
+                       else {
                                int handle_x, handle_y;
                                PanAuto *previous = 0, *next = 0;
                                double unit_position = mwindow->edl->local_session->get_selectionstart(1);
                                unit_position = mwindow->edl->align_to_frame(unit_position, 0);
                                unit_position = atrack->to_units(unit_position, 0);
                                PanAutos *ptr = (PanAutos*)atrack->automation->autos[AUTOMATION_PAN];
-                               ptr->get_handle(handle_x,
-                                       handle_y,
-                                       (long)unit_position,
-                                       PLAY_FORWARD,
-                                       previous,
-                                       next);
+                               ptr->get_handle(handle_x, handle_y, (long)unit_position,
+                                               PLAY_FORWARD, previous, next);
                                pan->update(handle_x, handle_y);
                        }
                        nudge->update();
                }
        }
        else
-       if(h - y1 >= mwindow->theme->pan_h)
-       {
-               patchbay->add_subwindow(pan = new APanPatch(mwindow,
-                       this,
-                       x1 + x,
-                       y1 + y));
-               x1 += pan->get_w() + 10;
-               patchbay->add_subwindow(nudge = new NudgePatch(mwindow,
-                       this,
-                       x1 + x,
-                       y1 + y,
-                       patchbay->get_w() - x1 - 10));
+       if( h - y1 >= mwindow->theme->pan_h ) {
+               patchbay->add_subwindow(mix = new AMixPatch(mwindow, this, x1+x, y1+y+5));
+               x1 += mix->get_w() + 10;
+               patchbay->add_subwindow(pan = new APanPatch(mwindow, this, x1+x, y1+y));
+               x1 += pan->get_w() + 20;
+               patchbay->add_subwindow(nudge = new NudgePatch(mwindow, this, x1+x, y1+y,
+                               patchbay->get_w() - x1-x - 10));
        }
        y1 += mwindow->theme->pan_h;
 
@@ -215,8 +173,7 @@ int APatchGUI::update(int x, int y)
 
 void APatchGUI::synchronize_fade(float value_change)
 {
-       if(fade && !change_source)
-       {
+       if( fade && !change_source ) {
                fade->update(fade->get_value() + value_change);
                fade->update_edl();
        }
@@ -256,22 +213,20 @@ float AFadePatch::update_edl()
 
 int AFadePatch::handle_event()
 {
-       if(shift_down())
-       {
+       if( shift_down() ) {
                update(0.0);
                set_tooltip(get_caption());
        }
 
        patch->change_source = 1;
        float change = update_edl();
-       if(patch->track->gang && patch->track->record)
+       if( patch->track->gang && patch->track->record )
                patch->patchbay->synchronize_faders(change, TRACK_AUDIO, patch->track);
        patch->change_source = 0;
 
        mwindow->sync_parameters(CHANGE_PARAMS);
 
-       if(mwindow->edl->session->auto_conf->autos[AUTOMATION_FADE])
-       {
+       if( mwindow->edl->session->auto_conf->autos[AUTOMATION_FADE] ) {
                mwindow->gui->draw_overlays(1);
        }
        return 1;
@@ -349,8 +304,7 @@ int APanPatch::handle_event()
 
        mwindow->sync_parameters(CHANGE_PARAMS);
 
-       if(need_undo && mwindow->edl->session->auto_conf->autos[AUTOMATION_PAN])
-       {
+       if( need_undo && mwindow->edl->session->auto_conf->autos[AUTOMATION_PAN] ) {
                mwindow->gui->draw_overlays(1);
        }
        return 1;
@@ -378,15 +332,9 @@ int AKeyPanPatch::handle_event()
 
 
 AMeterPatch::AMeterPatch(MWindow *mwindow, APatchGUI *patch, int x, int y)
- : BC_Meter(x,
-                       y,
-                       METER_HORIZ,
-                       patch->patchbay->get_w() - 10,
-                       mwindow->edl->session->min_meter_db,
-                       mwindow->edl->session->max_meter_db,
-                       mwindow->edl->session->meter_format,
-                       0,
-                       -1)
+ : BC_Meter(x, y, METER_HORIZ, patch->patchbay->get_w() - 10,
+       mwindow->edl->session->min_meter_db, mwindow->edl->session->max_meter_db,
+       mwindow->edl->session->meter_format, 0, -1)
 {
        this->mwindow = mwindow;
        this->patch = patch;
@@ -396,8 +344,7 @@ AMeterPatch::AMeterPatch(MWindow *mwindow, APatchGUI *patch, int x, int y)
 
 int AMeterPatch::button_press_event()
 {
-       if(cursor_inside() && is_event_win() && get_buttonpress() == 1)
-       {
+       if( cursor_inside() && is_event_win() && get_buttonpress() == 1 ) {
                mwindow->reset_meters();
                return 1;
        }
@@ -405,3 +352,13 @@ int AMeterPatch::button_press_event()
        return 0;
 }
 
+AMixPatch::AMixPatch(MWindow *mwindow, APatchGUI *patch, int x, int y)
+ : MixPatch(mwindow, patch, x, y)
+{
+       set_tooltip(_("Mixer"));
+}
+
+AMixPatch::~AMixPatch()
+{
+}
+
index 61b223f660218cb408b641a3ad360f44263b8a43..c8342057b0ad4f318372d79891bbca2dac11688d 100644 (file)
@@ -107,4 +107,11 @@ public:
        APatchGUI *patch;
 };
 
+class AMixPatch : public MixPatch
+{
+public:
+       AMixPatch(MWindow *mwindow, APatchGUI *patch, int x, int y);
+       ~AMixPatch();
+};
+
 #endif
index 24304c724b8cd7e6d6477a6539f137abb3529ed0..f5a3be2a37627b7b27cded03c82eb14b2a59b416 100644 (file)
@@ -44,6 +44,7 @@
 #include "tracks.h"
 #include "vwindow.h"
 #include "vwindowgui.h"
+#include "zwindow.h"
 
 
 AssetPopup::AssetPopup(MWindow *mwindow, AWindowGUI *gui)
@@ -67,6 +68,7 @@ void AssetPopup::create_objects()
        add_item(index = new AssetPopupBuildIndex(mwindow, this));
        add_item(view = new AssetPopupView(mwindow, this));
        add_item(view_window = new AssetPopupViewWindow(mwindow, this));
+       add_item(mixer = new AssetPopupMixer(mwindow, this));
        add_item(new AssetPopupPaste(mwindow, this));
        add_item(menu_item = new BC_MenuItem(_("Match...")));
        menu_item->add_submenu(submenu = new BC_SubMenu());
@@ -256,6 +258,44 @@ int AssetPopupViewWindow::handle_event()
        return 1;
 }
 
+AssetPopupMixer::AssetPopupMixer(MWindow *mwindow, AssetPopup *popup)
+ : BC_MenuItem(_("Open Mixers"))
+{
+       this->mwindow = mwindow;
+       this->popup = popup;
+}
+
+AssetPopupMixer::~AssetPopupMixer()
+{
+}
+
+int AssetPopupMixer::handle_event()
+{
+       mwindow->select_zwindow(0);
+       for( int i=0; i<mwindow->session->drag_assets->total; ++i ) {
+               Indexable *indexable = mwindow->session->drag_assets->values[i];
+               ArrayList<Indexable*> new_assets;
+               new_assets.append(indexable);
+               Track *track = mwindow->edl->tracks->last;
+               mwindow->load_assets(&new_assets, -1, LOADMODE_NEW_TRACKS, 0, 0, 0, 0, 0, 0);
+               track = !track ? mwindow->edl->tracks->first : track->next;
+               Mixer *mixer = 0;
+               ZWindow *zwindow = mwindow->get_mixer(mixer);
+               while( track ) {
+                       track->play = track->record = 0;
+                       mixer->mixer_ids.append(track->get_mixer_id());
+                       track = track->next;
+               }
+               char *path = indexable->path;
+               char *tp = strrchr(path, '/');
+               if( !tp ) tp = path; else ++tp;
+               zwindow->set_title(tp);
+               zwindow->start();
+       }
+        mwindow->queue_mixers(mwindow->edl,CURRENT_FRAME,0,0,1,0);
+       mwindow->resync_guis();
+       return 1;
+}
 
 AssetPopupPaste::AssetPopupPaste(MWindow *mwindow, AssetPopup *popup)
  : BC_MenuItem(_("Paste"))
index d6c3136e5a3c9e873ba85115b2f02c2f23081cf8..ee1a3d1f719ec78c98027fb1fdbafc8a644d996c 100644 (file)
@@ -54,6 +54,7 @@ public:
        AssetPopupBuildIndex *index;
        AssetPopupView *view;
        AssetPopupViewWindow *view_window;
+       AssetPopupMixer *mixer;
        AWindowListFormat *format;
 };
 
@@ -120,6 +121,18 @@ public:
        AssetPopup *popup;
 };
 
+class AssetPopupMixer : public BC_MenuItem
+{
+public:
+       AssetPopupMixer(MWindow *mwindow, AssetPopup *popup);
+       ~AssetPopupMixer();
+
+       int handle_event();
+
+       MWindow *mwindow;
+       AssetPopup *popup;
+};
+
 class AssetPopupPaste : public BC_MenuItem
 {
 public:
index 537f1174106e581df3a4eddfe7d5fc1cd1875d0a..66e2e39628b1d69641e7ffc8521f82fe8aff7b99 100644 (file)
@@ -28,6 +28,7 @@ class AssetPopupSort;
 class AssetPopupBuildIndex;
 class AssetPopupView;
 class AssetPopupViewWindow;
+class AssetPopupMixer;
 class AssetPopupPaste;
 class AssetMatchSize;
 class AssetMatchRate;
index 063f4e05c9a0f29032143850891afadfe7b0fddb..29d545045e9a96ccfaf2cc6c6710c65c4e9cb2c9 100644 (file)
@@ -233,6 +233,7 @@ void CWindow::update(int position,
 
        if(position)
        {
+               mwindow->queue_mixers(mwindow->edl, CURRENT_FRAME,1,0,1,0);
                playback_engine->que->send_command(CURRENT_FRAME,
                        CHANGE_NONE,
                        mwindow->edl,
index 20eff1207d05532fca714077f2b5c8c4b049bf72..95bae3979ce8071ca20358da276f75e33ea4b67c 100644 (file)
@@ -829,7 +829,7 @@ int CWindowSlider::handle_event()
 
 void CWindowSlider::set_position()
 {
-       double new_length = mwindow->edl->tracks->total_playable_length();
+       double new_length = mwindow->edl->tracks->total_length();
 //     if(mwindow->edl->local_session->preview_end <= 0 ||
 //             mwindow->edl->local_session->preview_end > new_length)
 //             mwindow->edl->local_session->preview_end = new_length;
index cd20a7b0d56e570d3a36de7b47bd6315fcff947e..a27e10cc5e37a287c5244ea22f222945a92ec035 100644 (file)
@@ -240,6 +240,7 @@ int EDL::load_xml(FileXML *file,
                        for(int i = 0; i < clips.size(); i++)
                                clips.get(i)->Garbage::remove_user();
                        clips.remove_all();
+                       mixers.remove_all_objects();
                }
 
                if(load_flags & LOAD_TIMEBAR)
@@ -299,6 +300,14 @@ int EDL::load_xml(FileXML *file,
                                        new_folder(folder);
                                }
                                else
+                               if(file->tag.title_is("MIXERS"))
+                               {
+                                       if((load_flags & LOAD_SESSION))
+                                               mixers.load(file);
+                                       else
+                                               result = file->skip_tag();
+                               }
+                               else
                                if(file->tag.title_is("ASSETS"))
                                {
                                        if(load_flags & LOAD_ASSETS)
@@ -413,6 +422,7 @@ int EDL::copy_all(EDL *edl)
        copy_session(edl);
        copy_assets(edl);
        copy_clips(edl);
+       copy_mixers(edl);
        tracks->copy_from(edl->tracks);
        labels->copy_from(edl->labels);
        return 0;
@@ -456,6 +466,12 @@ void EDL::copy_assets(EDL *edl)
        }
 }
 
+void EDL::copy_mixers(EDL *edl)
+{
+       if(this == edl) return;
+       mixers.copy_from(edl->mixers);
+}
+
 void EDL::copy_session(EDL *edl, int session_only)
 {
        if(this == edl) return;
@@ -629,6 +645,7 @@ int EDL::copy(double start,
                                        output_path,
                                        1,
                                        0);
+                       mixers.save(file);
                }
 
                file->append_newline();
@@ -1147,7 +1164,7 @@ void EDL::insert_asset(Asset *asset,
 
        if(new_nested_edl)
        {
-               length = new_nested_edl->tracks->total_playable_length();
+               length = new_nested_edl->tracks->total_length();
                layers = 1;
                channels = new_nested_edl->session->audio_channels;
        }
@@ -1479,7 +1496,7 @@ int EDL::get_sample_rate()
 
 int64_t EDL::get_audio_samples()
 {
-       return (int64_t)(tracks->total_playable_length() *
+       return (int64_t)(tracks->total_length() *
                session->sample_rate);
 }
 
@@ -1516,7 +1533,7 @@ int EDL::get_video_layers()
 
 int64_t EDL::get_video_frames()
 {
-       return (int64_t)(tracks->total_playable_length() *
+       return (int64_t)(tracks->total_length() *
                session->frame_rate);
 }
 
index 45740cdf05f2ec9a6f412a9a17d006d57d15d89e..2e8eec9c6e57efe650da415c9bcc6a42acd31079 100644 (file)
@@ -50,6 +50,7 @@
 #include "theme.inc"
 #include "tracks.inc"
 #include "vedit.inc"
+#include "zwindow.h"
 
 // Loading and saving are built on load and copy except for automation:
 
@@ -110,6 +111,7 @@ public:
        int copy_all(EDL *edl);
        void copy_assets(EDL *edl);
        void copy_clips(EDL *edl);
+       void copy_mixers(EDL *edl);
 // Copy pan and fade settings from edl
        void synchronize_params(EDL *edl);
 // Determine if the positions are equivalent if they're within half a frame
@@ -245,6 +247,7 @@ public:
        ArrayList<EDL*> vwindow_edls;
 // is the vwindow_edl shared and therefore should not be deleted in destructor
 //     int vwindow_edl_shared;
+       Mixers mixers;
 
 // Media files
 // Shared between all EDLs
index d01268618d80f17887547e1f04ad357d3a0f59b9..b18920349d34ccb8516030ba3e63209a995c9a4c 100644 (file)
@@ -190,8 +190,10 @@ GWindowColorButton::GWindowColorButton(GWindowToggle *auto_toggle, int x, int y,
 {
        this->auto_toggle = auto_toggle;
        this->color = 0;
-       for( int i=0; i<3; ++i )
+       for( int i=0; i<3; ++i ) {
                vframes[i] = new VFrame(w, w, BC_RGBA8888, -1);
+               vframes[i]->clear_frame();
+       }
 }
 
 GWindowColorButton::~GWindowColorButton()
index 9fb15e71b1e5b67d4e953916e6449e4c499bc794..aff99d6d69cb6880b264ca3af0c50fb79d57af5f 100644 (file)
@@ -229,22 +229,6 @@ KeyframePopupShow::~KeyframePopupShow()
 {
 }
 
-PatchGUI *KeyframePopupShow::get_patchgui(Track *track)
-{
-       PatchGUI *patchgui = 0;
-       TimelinePane **panes = mwindow->gui->pane;
-       for( int i=0; i<TOTAL_PANES && !patchgui; ++i ) {
-               if( !panes[i] ) continue;
-               PatchBay *patchbay = panes[i]->patchbay;
-               if( !patchbay ) continue;
-               for( int j=0; j<patchbay->patches.total && !patchgui; ++j ) {
-                       if( patchbay->patches.values[j]->track == track )
-                               patchgui = patchbay->patches.values[j];
-               }
-       }
-       return patchgui;
-}
-
 int KeyframePopupShow::handle_event()
 {
        MWindowGUI *mgui = mwindow->gui;
@@ -280,7 +264,7 @@ int KeyframePopupShow::handle_event()
 
                default: {
                        show_window = 0;
-                       PatchGUI *patchgui = get_patchgui(popup->keyframe_automation->track);
+                       PatchGUI *patchgui = mwindow->get_patchgui(popup->keyframe_automation->track);
                        if( !patchgui ) break;
 
                        switch( popup->keyframe_autos->autoidx ) {
index 68676792a0c66d692a3ab52f9f0bd9df95007dec..99220c94b5abfb4d197b3da938090ff623dbd224 100644 (file)
@@ -99,7 +99,6 @@ class KeyframePopupShow : public BC_MenuItem
 public:
        KeyframePopupShow(MWindow *mwindow, KeyframePopup *popup);
        ~KeyframePopupShow();
-       PatchGUI *get_patchgui(Track *track);
        int handle_event();
 
        MWindow *mwindow;
index a36efccec6a2cb0bcb11a329e8cec5d5e129c666..0bf2973d6273f21afabb506091b95586a234acd2 100644 (file)
@@ -256,6 +256,7 @@ void MainMenu::create_objects()
        windowmenu->add_item(new BC_MenuItem("-"));
        windowmenu->add_item(split_x = new SplitX(mwindow));
        windowmenu->add_item(split_y = new SplitY(mwindow));
+       windowmenu->add_item(mixer_viewer = new MixerViewer(mwindow));
        windowmenu->add_item(new TileWindows(mwindow,_("Default positions"),-1,_("Ctrl-P"),'p'));
        windowmenu->add_item(new TileWindows(mwindow,_("Tile left"),0));
        windowmenu->add_item(new TileWindows(mwindow,_("Tile right"),1));
@@ -1526,3 +1527,16 @@ int SplitY::handle_event()
 }
 
 
+MixerViewer::MixerViewer(MWindow *mwindow)
+ : BC_MenuItem(_("Mixer Viewer"), _("Shift-M"), 'M')
+{
+       this->mwindow = mwindow;
+       set_shift(1);
+}
+
+int MixerViewer::handle_event()
+{
+       mwindow->start_mixer();
+       return 1;
+}
+
index 6e277aedba2ab6bf6235833a27f4efb288805dda..8300bcb4a901cac017c49295f0223f902287694f 100644 (file)
@@ -43,6 +43,7 @@ class KeyframeCurveTypeMenu;
 class KeyframeCurveTypeItem;
 class SplitX;
 class SplitY;
+class MixerViewer;
 
 
 #include "arraylist.h"
@@ -146,6 +147,7 @@ public:
        ShowLWindow *show_lwindow;
        SplitX *split_x;
        SplitY *split_y;
+       MixerViewer *mixer_viewer;
 };
 
 // ========================================= edit
@@ -687,4 +689,12 @@ public:
        MWindow *mwindow;
 };
 
+class MixerViewer : public BC_MenuItem
+{
+public:
+       MixerViewer(MWindow *mwindow);
+       int handle_event();
+       MWindow *mwindow;
+};
+
 #endif
index 4ff969fdcc67f1168a475b4a7e473d3a6d1e362c..f7224b4c0cd84af9ca1174a908f4e79eb81203cf 100644 (file)
@@ -60,6 +60,8 @@ MainSession::MainSession(MWindow *mwindow)
        cwindow_fullscreen = 0;
        rwindow_fullscreen = 0;
        vwindow_fullscreen = 0;
+       zwindow_fullscreen = 0;
+       selected_zwindow = -1;
        actual_frame_rate = 0;
        window_config = 0;
        a_x11_host[0] = 0;
index 81b2439ff3e30f9fabaa645ea5c16d9a8aa259f8..ab53708d3048615fe11590a6c81cc71a7dc6ed9e 100644 (file)
@@ -173,7 +173,8 @@ public:
        int cwindow_fullscreen;
        int rwindow_fullscreen;
        int vwindow_fullscreen;
-
+       int zwindow_fullscreen;
+       int selected_zwindow;
 
        double actual_frame_rate;
 
index a0a661fdb930e9aed9692bf4a9875d624409cb6a..b1f8a050d6f1482c791ae9001cc8e91bb4b7ffd1 100644 (file)
@@ -281,7 +281,7 @@ void MenuEffectThread::run()
 
        if(mwindow->edl->local_session->get_selectionend() ==
                mwindow->edl->local_session->get_selectionstart())
-               total_end = mwindow->edl->tracks->total_playable_length();
+               total_end = mwindow->edl->tracks->total_length();
        else
                total_end = mwindow->edl->local_session->get_selectionend();
 
index 238c17aa43a09938d5a7bad1ade30d2fdef7e48e..9d3b4860858840b158f864ef4ae45943c7379659 100644 (file)
 #include "theme.h"
 #include "threadloader.h"
 #include "timebar.h"
+#include "timelinepane.h"
 #include "tipwindow.h"
 #include "trackcanvas.h"
 #include "track.h"
 #include "wavecache.h"
 #include "wwindow.h"
 #include "zoombar.h"
+#include "zwindow.h"
+#include "zwindowgui.h"
 #include "exportedl.h"
 
 #include "defaultformats.h"
@@ -182,6 +185,7 @@ MWindow::MWindow()
        plugin_gui_lock = new Mutex("MWindow::plugin_gui_lock");
        dead_plugin_lock = new Mutex("MWindow::dead_plugin_lock");
        vwindows_lock = new Mutex("MWindow::vwindows_lock");
+       zwindows_lock = new Mutex("MWindow::zwindows_lock");
        brender_lock = new Mutex("MWindow::brender_lock");
        keyframe_gui_lock = new Mutex("MWindow::keyframe_gui_lock");
 
@@ -274,6 +278,7 @@ MWindow::~MWindow()
        if( twindow && twindow->is_running() ) twindow->close_window();
        if( wwindow && wwindow->is_running() ) wwindow->close_window();
        vwindows.remove_all_objects();
+       zwindows.remove_all_objects();
        gui->close(0);
        if( awindow ) awindow->join();
        if( cwindow ) cwindow->join();
@@ -294,6 +299,7 @@ MWindow::~MWindow()
        close_gui(twindow);
        close_gui(wwindow);
        vwindows.remove_all_objects();
+       zwindows.remove_all_objects();
        gui->close(0);
        join();
 #endif
@@ -338,6 +344,7 @@ MWindow::~MWindow()
        delete dead_plugin_lock;
        delete plugin_gui_lock;
        delete vwindows_lock;
+       delete zwindows_lock;
        delete brender_lock;
        delete keyframe_gui_lock;
        colormodels.remove_all_objects();
@@ -1118,6 +1125,154 @@ VWindow *MWindow::get_viewer(int start_it, int idx)
        return vwindow;
 }
 
+ZWindow *MWindow::get_mixer(Mixer *&mixer)
+{
+       zwindows_lock->lock("MWindow::get_mixer");
+       if( !mixer ) mixer = edl->mixers.new_mixer();
+       ZWindow *zwindow = 0;
+       for( int i=0; !zwindow && i<zwindows.size(); ++i )
+               if( !zwindows[i]->is_running() ) zwindow = zwindows[i];
+       if( !zwindow )
+               zwindows.append(zwindow = new ZWindow(this));
+       zwindow->idx = mixer->idx;
+       zwindows_lock->unlock();
+       return zwindow;
+}
+
+void MWindow::del_mixer(ZWindow *zwindow)
+{
+       zwindows_lock->lock("MWindow::del_mixer 0");
+       edl->mixers.del_mixer(zwindow->idx);
+       zwindow->idx = -1;
+       if( session->selected_zwindow >= 0 ) {
+               int i = zwindows.number_of(zwindow);
+               if( i >= 0 && i < session->selected_zwindow )
+                       --session->selected_zwindow;
+               else if( i == session->selected_zwindow )
+                       session->selected_zwindow = -1;
+       }
+       zwindows_lock->unlock();
+       gui->lock_window("MWindow::del_mixer 1");
+       gui->update_mixers(0, -1);
+       gui->unlock_window();
+}
+
+void MWindow::start_mixer()
+{
+       Mixer *mixer = 0;
+       ZWindow *zwindow = get_mixer(mixer);
+       const char *title = 0;
+
+       for( Track *track=edl->tracks->first; track!=0; track=track->next ) {
+               PatchGUI *patchgui = get_patchgui(track);
+               if( !patchgui || !patchgui->mixer ) continue;
+               mixer->mixer_ids.append(track->get_mixer_id());
+               if( !title ) title = track->title;
+       }
+
+       session->selected_zwindow = -1;
+       gui->lock_window("MWindow::start_mixer");
+       gui->update_mixers(0, 0);
+       gui->unlock_window();
+
+       zwindow->set_title(title);
+       zwindow->start();
+       queue_mixers(edl,CURRENT_FRAME,0,0,1,0);
+}
+
+int MWindow::mixer_track_active(Track *track)
+{
+       int i = session->selected_zwindow;
+       if( i < 0 || i >= zwindows.size() ) return 0;
+       ZWindow *zwindow = zwindows[i];
+       Mixer *mixer = edl->mixers.get_mixer(zwindow->idx);
+       if( !mixer ) return 0;
+       int n = mixer->mixer_ids.number_of(track->get_mixer_id());
+       return n >= 0 ? 1 : 0;
+}
+
+void MWindow::update_mixer_tracks()
+{
+       zwindows_lock->lock("MixPatch::handle_event");
+       int i = session->selected_zwindow;
+       if( i >= 0 && i < zwindows.size() ) {
+               ZWindow *zwindow = zwindows[i];
+               zwindow->update_mixer_ids();
+       }
+       zwindows_lock->unlock();
+}
+
+void MWindow::queue_mixers(EDL *edl, int command, int wait_tracking,
+               int use_inout, int update_refresh, int toggle_audio)
+{
+       zwindows_lock->lock("MWindow::queue_mixers");
+       for( int vidx=0; vidx<zwindows.size(); ++vidx ) {
+               ZWindow *zwindow = zwindows[vidx];
+               if( !zwindow->running() ) continue;
+               Mixer *mixer = edl->mixers.get_mixer(zwindow->idx);
+               if( !mixer || !mixer->mixer_ids.size() ) continue;
+               int k = -1;
+               for( Track *track = edl->tracks->first; k<0 && track!=0; track=track->next ) {
+                       if( track->data_type != TRACK_VIDEO ) continue;
+                       int mixer_id = track->get_mixer_id();
+                       k = mixer->mixer_ids.size();
+                       while( --k >= 0 && mixer_id != mixer->mixer_ids[k] );
+               }
+               if( k < 0 ) continue;
+               EDL *mixer_edl = new EDL(this->edl);
+               mixer_edl->create_objects();
+               mixer_edl->copy_all(edl);
+               mixer_edl->remove_vwindow_edls();
+               for( Track *track = mixer_edl->tracks->first; track!=0; track=track->next ) {
+                       k = mixer->mixer_ids.size();
+                       while( --k >= 0 && track->get_mixer_id() != mixer->mixer_ids[k] );
+                       if( k >= 0 ) {
+                               track->record = 1;
+                               track->play = track->data_type == TRACK_VIDEO ? 1 : 0;
+                       }
+                       else
+                               track->record = track->play = 0;
+               }
+               zwindow->change_source(mixer_edl);
+               zwindow->issue_command(command,
+                       wait_tracking, use_inout, update_refresh, toggle_audio);
+       }
+       zwindows_lock->unlock();
+}
+
+void MWindow::stop_mixers()
+{
+       for( int vidx=0; vidx<zwindows.size(); ++vidx ) {
+               ZWindow *zwindow = zwindows[vidx];
+               if( !zwindow->running() ) continue;
+               zwindow->issue_command(STOP, 0, 0, 0, 0);
+       }
+}
+
+int MWindow::select_zwindow(ZWindow *zwindow)
+{
+       int ret = 0, n = zwindows.number_of(zwindow);
+       if( session->selected_zwindow != n ) {
+               session->selected_zwindow = n;
+               for( int i=0; i<zwindows.size(); ++i ) {
+                       ZWindow *zwindow = zwindows[i];
+                       if( !zwindow->running() ) continue;
+                       ZWindowGUI *zgui = zwindow->zgui;
+                       zgui->lock_window("MWindow::select_zwindow 0");
+                       zwindow->highlighted = i == n ? 1 : 0;
+                       if( zgui->draw_overlays() )
+                               zgui->canvas->get_canvas()->flash(1);
+                       zgui->unlock_window();
+               }
+               ret = 1;
+               gui->lock_window("MWindow::select_window 1");
+               gui->update_mixers(0, -1);
+               gui->unlock_window();
+       }
+       return ret;
+}
+
+
 void MWindow::init_cache()
 {
        audio_cache = new CICache(preferences);
@@ -1418,6 +1573,11 @@ void MWindow::stop_playback(int wait)
                if( !vwindow->is_running() ) continue;
                vwindow->playback_engine->stop_playback();
        }
+       for(int i = 0; i < zwindows.size(); i++) {
+               ZWindow *zwindow = zwindows[i];
+               if( !zwindow->is_running() ) continue;
+               zwindow->zgui->playback_engine->stop_playback();
+       }
        if( locked ) gui->lock_window("MWindow::stop_playback");
 }
 
@@ -1820,7 +1980,7 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
                edl->session->proxy_use_scaler = 0;
                edl->session->proxy_auto_scale = 0;
                edl->local_session->preview_start = 0;
-               edl->local_session->preview_end = edl->tracks->total_playable_length();
+               edl->local_session->preview_end = edl->tracks->total_length();
                edl->local_session->loop_playback = 0;
                edl->local_session->set_selectionstart(0);
                edl->local_session->set_selectionend(0);
@@ -2504,6 +2664,7 @@ void MWindow::sync_parameters(int change_type)
        }
        else
        {
+               queue_mixers(edl,CURRENT_FRAME,0,0,1,0);
                cwindow->playback_engine->que->send_command(CURRENT_FRAME,
                                                        change_type,
                                                        edl,
@@ -3022,8 +3183,8 @@ void MWindow::update_project(int load_mode)
        if(debug) PRINT_TRACE
 
 // Close all the vwindows
-       if(load_mode == LOADMODE_REPLACE ||
-               load_mode == LOADMODE_REPLACE_CONCATENATE) {
+       if( load_mode == LOADMODE_REPLACE ||
+           load_mode == LOADMODE_REPLACE_CONCATENATE ) {
                if(debug) PRINT_TRACE
                int first_vwindow = 0;
                if(session->show_vwindow) first_vwindow = 1;
@@ -3041,13 +3202,28 @@ void MWindow::update_project(int load_mode)
                        vwindow->close_window();
                }
                if(debug) PRINT_TRACE
+               select_zwindow(0);
+               for( int i=0; i<zwindows.size(); ++i ) {
+                       ZWindow *zwindow = zwindows[i];
+                       if( !zwindow->is_running() ) continue;
+                       zwindow->close_window();
+               }
+
+               for( int i=0; i<edl->mixers.size(); ++i ) {
+                       Mixer *mixer = edl->mixers[i];
+                       ZWindow *zwindow = get_mixer(mixer);
+                       zwindow->set_title(mixer->title);
+                       zwindow->start();
+               }
        }
-       else if(vwindows.size()) {
-               VWindow *vwindow = vwindows[DEFAULT_VWINDOW];
-               if( vwindow->is_running() ) {
-                       vwindow->gui->lock_window("MWindow::update_project");
-                       vwindow->update(1);
-                       vwindow->gui->unlock_window();
+       else {
+               if(vwindows.size()) {
+                       VWindow *vwindow = vwindows[DEFAULT_VWINDOW];
+                       if( vwindow->is_running() ) {
+                               vwindow->gui->lock_window("MWindow::update_project");
+                               vwindow->update(1);
+                               vwindow->gui->unlock_window();
+                       }
                }
        }
 
@@ -3066,6 +3242,7 @@ void MWindow::update_project(int load_mode)
        if(debug) PRINT_TRACE
 
        gui->lock_window("MWindow::update_project");
+       gui->update_mixers(0, 0);
        gui->flush();
        if(debug) PRINT_TRACE
 }
@@ -3198,6 +3375,8 @@ int MWindow::create_aspect_ratio(float &w, float &h, int width, int height)
 
 void MWindow::reset_caches()
 {
+       gui->resource_thread->get_video_source(0);
+       gui->resource_thread->get_audio_source(0);
        frame_cache->remove_all();
        wave_cache->remove_all();
        audio_cache->remove_all();
@@ -3838,4 +4017,19 @@ PanAuto* MWindow::get_pan_auto(PatchGUI *patch)
        return (PanAuto*)ptr->get_prev_auto( (long)unit_position, PLAY_FORWARD, current);
 }
 
+PatchGUI *MWindow::get_patchgui(Track *track)
+{
+       PatchGUI *patchgui = 0;
+       TimelinePane **panes = gui->pane;
+        for( int i=0; i<TOTAL_PANES && !patchgui; ++i ) {
+                if( !panes[i] ) continue;
+                PatchBay *patchbay = panes[i]->patchbay;
+                if( !patchbay ) continue;
+                for( int j=0; j<patchbay->patches.total && !patchgui; ++j ) {
+                        if( patchbay->patches.values[j]->track == track )
+                                patchgui = patchbay->patches.values[j];
+                }
+        }
+        return patchgui;
+}
 
index a7bd7e3d507f38f2df50479d3045ebee65fa6a71..8f26357ecb5d1ef73957295d03bdf596d1944d37 100644 (file)
@@ -95,6 +95,7 @@
 #include "videowindow.inc"
 #include "vpatchgui.h"
 #include "vwindow.inc"
+#include "zwindow.inc"
 #include "wwindow.inc"
 #include "wavecache.inc"
 
@@ -203,8 +204,15 @@ public:
        void dump_plugindb(FILE *fp);
        void stop_playback(int wait=0);
 
-
-
+       void queue_mixers(EDL *edl, int command, int wait_tracking,
+               int use_inout, int update_refresh, int toggle_audio);
+       void stop_mixers();
+       ZWindow *get_mixer(Mixer *&mixer);
+       void del_mixer(ZWindow *zwindow);
+       int mixer_track_active(Track *track);
+       void update_mixer_tracks();
+       void start_mixer();
+       int select_zwindow(ZWindow *zwindow);
 
        int load_filenames(ArrayList<char*> *filenames,
                int load_mode = LOADMODE_REPLACE,
@@ -494,6 +502,7 @@ public:
        FloatAuto* get_float_auto(PatchGUI *patch,int idx);
        IntAuto* get_int_auto(PatchGUI *patch,int idx);
        PanAuto* get_pan_auto(PatchGUI *patch);
+       PatchGUI *get_patchgui(Track *track);
 
        int modify_edithandles();
        int modify_pluginhandles();
@@ -600,6 +609,9 @@ public:
 // Viewer
        Mutex *vwindows_lock;
        ArrayList<VWindow*> vwindows;
+// Mixer
+       Mutex *zwindows_lock;
+       ArrayList<ZWindow*> zwindows;
 // Asset manager
        AWindow *awindow;
 // Automation window
index 366236ffc28936958dd75402faa5d2eb52e35b66..9e872bc1d0519e3dec00b1585217038f1aa8ebd4 100644 (file)
@@ -97,6 +97,7 @@ N_("Cinelerra: Load")
 N_("Cinelerra: Loading")
 N_("Cinelerra: Locate file")
 N_("Cinelerra: Mask")
+N_("Cinelerra: Mixer")
 N_("Cinelerra: New folder")
 N_("Cinelerra: New Project")
 N_("Cinelerra: Normalize")
index a149b27557fcdfe755678808719e33d5e6cfe1fc..4d77f8a96b48d18d0eeeb380a8af57d9a4e8c758 100644 (file)
@@ -1092,7 +1092,7 @@ void MWindow::overwrite(EDL *source)
        }
 
        source->copy(src_start, src_start + overwrite_len,
-               1, 0, 0, &file, "", 1);
+               0, 0, 0, &file, "", 1);
 
 // HACK around paste_edl get_start/endselection on its own
 // so we need to clear only when not using both io points
@@ -1330,7 +1330,7 @@ int MWindow::paste_edls(ArrayList<EDL*> *new_edls, int load_mode,
        if( !new_edls->total ) return 0;
 
 //PRINT_TRACE
-//     double original_length = edl->tracks->total_playable_length();
+//     double original_length = edl->tracks->total_length();
 //     double original_preview_end = edl->local_session->preview_end;
 //PRINT_TRACE
 
@@ -1344,6 +1344,7 @@ int MWindow::paste_edls(ArrayList<EDL*> *new_edls, int load_mode,
                edl = new EDL;
                edl->create_objects();
                edl->copy_session(new_edls->values[0]);
+               edl->copy_mixers(new_edls->values[0]);
                gui->mainmenu->update_toggles(0);
                gui->unlock_window();
                gwindow->gui->update_toggles(1);
@@ -1605,7 +1606,7 @@ int MWindow::paste_edls(ArrayList<EDL*> *new_edls, int load_mode,
 // Fix preview range
 //     if( EQUIV(original_length, original_preview_end) )
 //     {
-//             edl->local_session->preview_end = edl->tracks->total_playable_length();
+//             edl->local_session->preview_end = edl->tracks->total_length();
 //     }
 
 // Start examining next batch of index files
index 7587d46dee0fbbfa8e296eecd22c21335875d4de..8825e25d7e680b4167f85f064642273518710c39 100644 (file)
@@ -2236,6 +2236,23 @@ void MWindowGUI::draw_trackmovement()
 }
 
 
+void MWindowGUI::update_mixers(Track *track, int v)
+{
+       for( int i=0; i<TOTAL_PANES;  ++i ) {
+               if( !pane[i] ) continue;
+               PatchBay *patchbay = pane[i]->patchbay;
+               if( !patchbay ) continue;
+               for( int j=0; j<patchbay->patches.total; ++j ) {
+                       PatchGUI *patchgui = patchbay->patches.values[j];
+                       if( !patchgui->mix ) continue;
+                       if( !track || patchgui->track == track ) {
+                               patchgui->mix->update(v>=0 ? v :
+                                       mwindow->mixer_track_active(patchgui->track));
+                       }
+               }
+       }
+}
+
 PaneButton::PaneButton(MWindow *mwindow, int x, int y)
  : BC_Button(x, y, mwindow->theme->get_image_set("pane"))
 {
index 2d5fd10cbe97d419e89532b59668b7943e79338a..4eb54cf0a41c02e6a63fe483155bfff32160f2d1 100644 (file)
@@ -51,6 +51,7 @@
 #include "statusbar.inc"
 #include "swindow.inc"
 #include "timelinepane.inc"
+#include "track.inc"
 #include "trackcanvas.inc"
 #include "trackscroll.inc"
 #include "transitionpopup.inc"
@@ -127,6 +128,7 @@ public:
        void set_playing_back(int value);
        void set_editing_mode(int flush);
        void set_meter_format(int mode, int min, int max);
+       void update_mixers(Track *track, int v);
 
        int translation_event();
        int resize_event(int w, int h);          // handle a resize event
index 3a20d44c32db3e1636475ff578c175e2ee176aab..a2a19864703cb2cb9ff1c6b46b8c3ec741fe675f 100644 (file)
@@ -42,7 +42,7 @@
 #include "tracks.h"
 #include "transportque.h"
 #include "vframe.h"
-
+#include "zwindow.h"
 
 
 PatchGUI::PatchGUI(MWindow *mwindow,
@@ -65,22 +65,24 @@ PatchGUI::PatchGUI(MWindow *mwindow,
        mute = 0;
        expand = 0;
        nudge = 0;
+       mix = 0;
        change_source = 0;
-       track_id = -1;
-       if(track) track_id = track->get_id();
+       track_id = track ? track->get_id() : -1;
+       mixer = 0;
 }
 
 PatchGUI::~PatchGUI()
 {
-       if(title) delete title;
-       if(record) delete record;
-       if(play) delete play;
-//     if(automate) delete automate;
-       if(gang) delete gang;
-       if(draw) delete draw;
-       if(mute) delete mute;
-       if(expand) delete expand;
-       if(nudge) delete nudge;
+       delete title;
+       delete record;
+       delete play;
+//     delete automate;
+       delete gang;
+       delete draw;
+       delete mute;
+       delete expand;
+       delete nudge;
+       delete mix;
 }
 
 void PatchGUI::create_objects()
@@ -789,5 +791,34 @@ void NudgePatch::update()
 }
 
 
+MixPatch::MixPatch(MWindow *mwindow, PatchGUI *patch, int x, int y)
+ : BC_Toggle(x, y, mwindow->theme->get_image_set("mixpatch_data"),
+       patch->mixer, "", 0, 0, 0)
+{
+       this->mwindow = mwindow;
+       this->patch = patch;
+}
+
+MixPatch::~MixPatch()
+{
+}
+
+int MixPatch::handle_event()
+{
+       int v = patch->track ? get_value() : 0;
+       if( patch->mixer != v ) {
+               if( patch->track )
+                       mwindow->gui->update_mixers(patch->track, v);
+               else
+                       update(v);
+               mwindow->update_mixer_tracks();
+       }
+       return 1;
+}
 
+void MixPatch::update(int v)
+{
+       patch->mixer = v;
+       BC_Toggle::update(v);
+}
 
index e16dfce55ee8a2c8fa399d94efdc04f36c55ab8c..126b06661a0113d473d698c9e012bd1fed6628ba 100644 (file)
@@ -40,6 +40,7 @@ class DrawPatch;
 class MutePatch;
 class ExpandPatch;
 class NudgePatch;
+class MixPatch;
 
 class PatchGUI
 {
@@ -69,7 +70,7 @@ public:
 // Used by update routines so non-existent track doesn't need to be dereferenced
 // to know it doesn't match the current EDL.
        int track_id;
-       int data_type;
+       int data_type, mixer;
        int x, y;
 // Don't synchronize the fader if this is true.
        int change_source;
@@ -83,6 +84,7 @@ public:
        MutePatch *mute;
        ExpandPatch *expand;
        NudgePatch *nudge;
+       MixPatch *mix;
        char string_return[BCTEXTLEN];
 };
 
@@ -181,5 +183,17 @@ public:
        PatchGUI *patch;
 };
 
+class MixPatch : public BC_Toggle
+{
+public:
+       MixPatch(MWindow *mwindow, PatchGUI *patch, int x, int y);
+       ~MixPatch();
+       int handle_event();
+       void update(int v);
+
+       MWindow *mwindow;
+       PatchGUI *patch;
+};
+
 
 #endif
index 7dcea2df1f6203d348dbb5ad096e0f427c535699..0918ead4e449ae1232459214f575698973ffdb2c 100644 (file)
@@ -425,3 +425,68 @@ void PlaybackEngine::stop_playback()
        renderengine_lock->unlock();
 }
 
+
+void PlaybackEngine::issue_command(EDL *edl, int command, int wait_tracking,
+               int use_inout, int update_refresh, int toggle_audio)
+{
+//printf("PlayTransport::handle_transport 1 %d\n", command);
+// Stop requires transferring the output buffer to a refresh buffer.
+       int do_stop = 0, resume = 0;
+       int prev_command = this->command->command;
+       int prev_single_frame = this->command->single_frame();
+       int prev_audio = this->command->audio_toggle ?
+                !prev_single_frame : prev_single_frame;
+       int cur_single_frame = TransportCommand::single_frame(command);
+       int cur_audio = toggle_audio ?
+                !cur_single_frame : cur_single_frame;
+
+// Dispatch command
+       switch(command) {
+       case FAST_REWIND:       // Commands that play back
+       case NORMAL_REWIND:
+       case SLOW_REWIND:
+       case SINGLE_FRAME_REWIND:
+       case SINGLE_FRAME_FWD:
+       case SLOW_FWD:
+       case NORMAL_FWD:
+       case FAST_FWD:
+               if( !prev_single_frame &&
+                   prev_command == command &&
+                   cur_audio == prev_audio ) {
+// Same direction pressed twice and no change in audio state,  Stop
+                       do_stop = 1;
+                       break;
+               }
+// Resume or change direction
+               switch( prev_command ) {
+               default:
+                       que->send_command(STOP, CHANGE_NONE, 0, 0);
+                       interrupt_playback(wait_tracking);
+                       resume = 1;
+// fall through
+               case STOP:
+               case COMMAND_NONE:
+               case SINGLE_FRAME_FWD:
+               case SINGLE_FRAME_REWIND:
+// Start from scratch
+                       que->send_command(command, CHANGE_NONE, edl,
+                               1, resume, use_inout, toggle_audio,
+                               mwindow->preferences->forward_render_displacement);
+                       break;
+               }
+               break;
+
+// Commands that stop
+       case STOP:
+       case REWIND:
+       case GOTO_END:
+               do_stop = 1;
+               break;
+       }
+
+       if( do_stop ) {
+               que->send_command(STOP, CHANGE_NONE, 0, 0);
+               interrupt_playback(wait_tracking);
+       }
+}
+
index 9d2d35e338f9f9e0708179042cc62ac5b28d89c2..1dd0482e3232218620c48e376be3aa04aa267d14 100644 (file)
@@ -82,6 +82,8 @@ public:
 
        void run();
        void stop_playback();
+       void issue_command(EDL *edl, int command, int wait_tracking,
+               int use_inout, int update_refresh, int toggle_audio);
 
 // Maintain caches through console changes
        CICache *audio_cache, *video_cache;
index 6fc55d63d376f12fefd1d68dff011764b8344e2f..c7334213e7f3c13e68463cfa668faba41041c460 100644 (file)
@@ -179,8 +179,13 @@ int PlayTransport::flip_vertical(int vertical, int &x, int &y)
 
 int PlayTransport::keypress_event()
 {
-       int result = 1;
        int key = subwindow->get_keypress();
+       return do_keypress(key);
+}
+
+int PlayTransport::do_keypress(int key)
+{
+       int result = 1;
 // unqualified keys, still holding lock
        switch( key ) {
        case HOME:
@@ -275,71 +280,13 @@ void PlayTransport::goto_end()
 void PlayTransport::handle_transport(int command,
        int wait_tracking, int use_inout, int update_refresh, int toggle_audio)
 {
-       if( !get_edl() ) return;
-
-// Stop requires transferring the output buffer to a refresh buffer.
-       int do_stop = 0;
-       int resume = 0;
-//printf("PlayTransport::handle_transport 1 %d\n", command);
-       int prev_command = engine->command->command;
-       int prev_single_frame = engine->command->single_frame();
-       int prev_audio = engine->command->audio_toggle ?
-                !prev_single_frame : prev_single_frame;
-       int cur_single_frame = TransportCommand::single_frame(command);
-       int cur_audio = toggle_audio ?
-                !cur_single_frame : cur_single_frame;
-
-// Dispatch command
-       switch(command) {
-       case FAST_REWIND:       // Commands that play back
-       case NORMAL_REWIND:
-       case SLOW_REWIND:
-       case SINGLE_FRAME_REWIND:
-       case SINGLE_FRAME_FWD:
-       case SLOW_FWD:
-       case NORMAL_FWD:
-       case FAST_FWD:
-               if( !prev_single_frame &&
-                   prev_command == command &&
-                   cur_audio == prev_audio ) {
-// Same direction pressed twice and no change in audio state,  Stop
-                       do_stop = 1;
-                       break;
-               }
-// Resume or change direction
-               switch( prev_command ) {
-               default:
-                       engine->que->send_command(STOP, CHANGE_NONE, 0, 0);
-                       engine->interrupt_playback(wait_tracking);
-                       resume = 1;
-// fall through
-               case STOP:
-               case COMMAND_NONE:
-               case SINGLE_FRAME_FWD:
-               case SINGLE_FRAME_REWIND:
-// Start from scratch
-                       engine->que->send_command(command, CHANGE_NONE, get_edl(),
-                               1, resume, use_inout, toggle_audio,
-                               mwindow->preferences->forward_render_displacement);
-                       break;
-               }
-               break;
-
-// Commands that stop
-       case STOP:
-       case REWIND:
-       case GOTO_END:
-               do_stop = 1;
-               break;
-       }
-
-       if( do_stop ) {
-               engine->que->send_command(STOP, CHANGE_NONE, 0, 0);
-               engine->interrupt_playback(wait_tracking);
-       }
+       EDL *edl = get_edl();
+       if( !edl ) return;
+       if( !is_vwindow() )
+               mwindow->queue_mixers(edl, command, wait_tracking, use_inout, update_refresh, toggle_audio);
+       engine->issue_command(edl, command, wait_tracking, use_inout, update_refresh, toggle_audio);
 }
 
-
 EDL* PlayTransport::get_edl()
 {
        return mwindow->edl;
@@ -514,8 +461,7 @@ int StopButton::handle_event()
 
 void PlayTransport::change_position(double position)
 {
-       EDL *edl = get_edl();
-       if( !edl ) return;
+       if( !get_edl() ) return;
        int prev_command = engine->command->command;
 // stop transport
        if( prev_command != STOP && prev_command != COMMAND_NONE &&
index 11233b2b1030cd363e30e837cb87b15d198b0382..62d1973aff2e440da366473f27d86e3a0399a3dc 100644 (file)
@@ -49,6 +49,7 @@ public:
        static int get_transport_width(MWindow *mwindow);
        int flip_vertical(int vertical, int &x, int &y);
        int keypress_event();
+       int do_keypress(int key);
 // Abstract TransportQue::send_command.
 // wait_tracking - causes stop to wail until the final tracking position
 // is updated before returning
@@ -65,6 +66,7 @@ public:
 // Get the EDL to play back with default to mwindow->edl
        virtual EDL* get_edl();
        void change_position(double position);
+       virtual int is_vwindow() { return 0; }
 
 // playback parameters
        int reverse;
index 628255b56a814c5a44996ed8cfb84e4fc21e7566..f5c0754a589da98204943629fd62bb2aa470b6b3 100644 (file)
@@ -90,7 +90,7 @@ RenderEngine::~RenderEngine()
        delete interrupt_lock;
        delete first_frame_lock;
        delete config;
-       edl->Garbage::remove_user();
+       if( edl ) edl->Garbage::remove_user();
 }
 
 EDL* RenderEngine::get_edl()
index 8b3bc74a9a062552e05969ba48289ef4476752dd..00dee98145f3c773b7fad2c548765084972bf45c 100644 (file)
@@ -132,6 +132,7 @@ int Save::save_before_quit()
 SaveAs::SaveAs(MWindow *mwindow)
  : BC_MenuItem(_("Save as..."), "Shift-S", 'S'), Thread()
 {
+       set_shift(1);
        this->mwindow = mwindow;
        quit_now = 0;
 }
index bddba8783277c220524e45b5d42fdb5577a5ef93..be8aac82829d1d22aa53f733df739b5255774893 100644 (file)
@@ -238,6 +238,8 @@ void Theme::initialize()
        new_image("awindow_icon", "heroine_icon.png");
        new_image("record_icon", "heroine_icon.png");
        new_image("clip_icon", "clip_icon.png");
+       new_image_set("mixpatch_data", 5, "mixpatch_up.png", "mixpatch_hi.png",
+               "mixpatch_checked.png", "mixpatch_dn.png", "mixpatch_checkedhi.png");
 
 
        new_image("aeffect_icon", "aeffect_icon.png");
@@ -951,8 +953,8 @@ void Theme::get_vwindow_sizes(VWindowGUI *gui)
                        widget_border;
 
                vdivision_x = 280;
-               vtime_x = vdivision_x;
-               vtime_y = vedit_y + 20;
+               vtime_x = vedit_x + 20; //vdivision_x;
+               vtime_y = vedit_y + 30; //+ 20;
        }
        else
        {
index d33d4ea32e85b14cdfbd10652739719a8435c096..03fa0357526810069023c7e9bd528a6ebdd2530a 100644 (file)
@@ -522,8 +522,8 @@ double TimeBar::get_edl_length()
        edl_length = 0;
 
        if( get_edl() ) {
-//printf("TimeBar::get_edl_length 1 %f\n", get_edl()->tracks->total_playable_length());
-               edl_length = get_edl()->tracks->total_playable_length();
+//printf("TimeBar::get_edl_length 1 %f\n", get_edl()->tracks->total_length());
+               edl_length = get_edl()->tracks->total_length();
        }
 
 //printf("TimeBar::get_edl_length 2\n");
index f3852cf90e5bab5308e9383aeb29324dbb061a15..e3f624c0e3fc4564f92b6dc76c90705d237e0091 100644 (file)
@@ -66,6 +66,7 @@ Track::Track(EDL *edl, Tracks *tracks) : ListItem<Track>()
        track_w = edl->session->output_w;
        track_h = edl->session->output_h;
        id = EDL::next_id();
+       mixer_id = -1;
 }
 
 Track::~Track()
@@ -87,6 +88,7 @@ int Track::copy_settings(Track *track)
        this->gang = track->gang;
        this->record = track->record;
        this->nudge = track->nudge;
+       this->mixer_id = track->mixer_id;
        this->play = track->play;
        this->track_w = track->track_w;
        this->track_h = track->track_h;
@@ -321,6 +323,7 @@ int Track::load(FileXML *file, int track_offset, uint32_t load_flags)
        gang = file->tag.get_property("GANG", gang);
        draw = file->tag.get_property("DRAW", draw);
        nudge = file->tag.get_property("NUDGE", nudge);
+       mixer_id = file->tag.get_property("MIXER_ID", mixer_id);
        expand_view = file->tag.get_property("EXPAND", expand_view);
        track_w = file->tag.get_property("TRACK_W", track_w);
        track_h = file->tag.get_property("TRACK_H", track_h);
@@ -1068,6 +1071,7 @@ int Track::copy(double start,
        file->tag.set_title("TRACK");
        file->tag.set_property("RECORD", record);
        file->tag.set_property("NUDGE", nudge);
+       file->tag.set_property("MIXER_ID", mixer_id);
        file->tag.set_property("PLAY", play);
        file->tag.set_property("GANG", gang);
        file->tag.set_property("DRAW", draw);
@@ -1866,3 +1870,14 @@ int Track::plugin_exists(Plugin *plugin)
        return 0;
 }
 
+int Track::get_mixer_id()
+{
+       if( mixer_id < 0 ) {
+               int v = 0;
+               for( Track *track=tracks->first; track!=0; track=track->next )
+                       if( track->mixer_id > v ) v = track->mixer_id;
+               mixer_id = v + 1;
+       }
+       return mixer_id;
+}
+
index c8e561ff4465197282af29d69f160be6527eaf1a..1f6283f3a3190455ffde6cb812a123b3fc0e0b4f 100644 (file)
@@ -69,6 +69,7 @@ public:
        virtual int load_header(FileXML *file, uint32_t load_flags) { return 0; };
        virtual int load_derived(FileXML *file, uint32_t load_flags) { return 0; };
        void equivalent_output(Track *track, double *result);
+       int get_mixer_id();
 
        virtual void copy_from(Track *track);
        Track& operator=(Track& track);
@@ -173,9 +174,6 @@ public:
        int plugin_used(int64_t position, int64_t direction);
 
 
-
-
-
        virtual int copy_settings(Track *track);
        void shift_keyframes(int64_t position, int64_t length);
        void shift_effects(int64_t position, int64_t length, int edit_autos);
@@ -213,23 +211,6 @@ public:
        int data_type;
 
 
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
        int load_automation(FileXML *file);
        int load_edits(FileXML *file);
 
@@ -374,9 +355,7 @@ public:
        int pixel;   // pixel position from top of track view
 // Dimensions of this track if video
        int track_w, track_h;
-
-
-
+       int mixer_id;
 
 private:
 // Identification of the track
index 91609c3c3162e2558edfdd64aaf451597b540a3b..4ba197e5cec27c5e9054a90639fc9431adab38e7 100644 (file)
@@ -98,6 +98,7 @@ int Tracking::stop_playback()
 //             Thread::cancel();
                Thread::join();
 
+               mwindow->stop_mixers();
 // Final position is updated continuously during playback
 // Get final position
                double position = get_tracking_position();
index 8db132bc1eff7c9c50838b9147d46d9745c57bef..1eec0d4179c1dcae49829432aa7027c5c4666e6a 100644 (file)
@@ -491,15 +491,18 @@ double Tracks::total_playable_length()
        double total = 0;
        for(Track *current = first; current; current = NEXT)
        {
-               double length = current->get_length();
-               if(length > total) total = length;
+               if( current->play )
+               {
+                       double length = current->get_length();
+                       if(length > total) total = length;
+               }
        }
        return total;
 }
 
 double Tracks::total_recordable_length()
 {
-       double total = 0;
+       double total = -1;
        for(Track *current = first; current; current = NEXT)
        {
                if(current->record)
@@ -516,7 +519,8 @@ double Tracks::total_length()
        double total = 0;
        for(Track *current = first; current; current = NEXT)
        {
-               if(current->get_length() > total) total = current->get_length();
+               double length = current->get_length();
+               if(length > total) total = length;
        }
        return total;
 }
index 01ba565d3bf60953085021c771516c3009ec6d21..a2a5160a1dade23ebeb0116df585d8379da7b5ed 100644 (file)
@@ -184,6 +184,9 @@ void TransportCommand::set_playback_range(EDL *edl,
                end_position = end;
        }
        else {
+// starting play at or past end, play to end of media (for mixers)
+               if( start >= length )
+                       length = edl->tracks->total_length();
                switch( command ) {
                case SLOW_FWD:
                case FAST_FWD:
@@ -251,8 +254,11 @@ void TransportCommand::playback_range_inout()
 
        if(edl->local_session->outpoint_valid())
                end_position = edl->local_session->get_outpoint();
-       else
+       else {
                end_position = edl->tracks->total_playable_length();
+               if( start_position >= end_position )
+                       end_position = edl->tracks->total_length();
+       }
 }
 
 void TransportCommand::playback_range_project()
index f8469b10410d67f2179fe869aae8b3638866f2e8..c40f72d8b31efb01b2c927e308419a6672a9c5c6 100644 (file)
@@ -147,7 +147,7 @@ int64_t VEdit::get_source_end(int64_t default_)
 
        if(nested_edl)
        {
-               return (int64_t)(nested_edl->tracks->total_playable_length() *
+               return (int64_t)(nested_edl->tracks->total_length() *
                        edl->session->frame_rate + 0.5);
        }
 
index 0c8e1b7fdec53176caf4bb0f0288f17ecf4f15e3..28f5a6d323db3e20d94acd23129b6b54dcff1a80 100644 (file)
@@ -293,7 +293,7 @@ int VModule::import_frame(VFrame *output, VEdit *current_edit,
                        }
                        else
                        {
-                               max_position = Units::to_int64(nested_edl->tracks->total_playable_length() *
+                               max_position = Units::to_int64(nested_edl->tracks->total_length() *
                                        frame_rate - 1);
                        }
 
index dca01ad3a6806633a1344d8a073598f3a72fa4c8..8b9c0b4766d626c5f9c5b05e38999131d61f2363 100644 (file)
 #include "trackcanvas.h"
 #include "vpatchgui.h"
 #include "vtrack.h"
+#include "vwindow.h"
 
 #include <string.h>
 
 
-
-
-
 VPatchGUI::VPatchGUI(MWindow *mwindow, PatchBay *patchbay, VTrack *track, int x, int y)
  : PatchGUI(mwindow, patchbay, track, x, y)
 {
@@ -58,8 +56,8 @@ VPatchGUI::VPatchGUI(MWindow *mwindow, PatchBay *patchbay, VTrack *track, int x,
 
 VPatchGUI::~VPatchGUI()
 {
-       if(fade) delete fade;
-       if(mode) delete mode;
+       if( fade ) delete fade;
+       if( mode ) delete mode;
 }
 
 void VPatchGUI::create_objects()
@@ -72,20 +70,16 @@ int VPatchGUI::reposition(int x, int y)
        //int x1 = 0;
        int y1 = PatchGUI::reposition(x, y);
 
-       if(fade) fade->reposition_window(fade->get_x(),
-               y1 + y);
-
+       if( fade )
+               fade->reposition_window(fade->get_x(), y1+y);
        y1 += mwindow->theme->fade_h;
-
-       if(mode) mode->reposition_window(mode->get_x(),
-               y1 + y);
-
-       if(nudge) nudge->reposition_window(nudge->get_x(),
-               y1 + y);
-
-
+       if( mix )
+               mix->reposition_window(mix->get_x(), y1+y);
+       if( mode )
+               mode->reposition_window(mode->get_x(), y1+y);
+       if( nudge )
+               nudge->reposition_window(nudge->get_x(), y1+y);
        y1 += mwindow->theme->mode_h;
-
        return y1;
 }
 
@@ -95,68 +89,51 @@ int VPatchGUI::update(int x, int y)
        int x1 = 0;
        int y1 = PatchGUI::update(x, y);
 
-       if(fade)
-       {
-               if(h - y1 < mwindow->theme->fade_h)
-               {
+       if( fade ) {
+               if( h - y1 < mwindow->theme->fade_h ) {
                        delete fade;
                        fade = 0;
                }
-               else
-               {
+               else {
                        fade->update(fade->get_w(), mwindow->get_float_auto(this, AUTOMATION_FADE)->get_value(),
                                     mwindow->edl->local_session->automation_mins[AUTOGROUPTYPE_VIDEO_FADE],
                                     mwindow->edl->local_session->automation_maxs[AUTOGROUPTYPE_VIDEO_FADE]);
                }
        }
        else
-       if(h - y1 >= mwindow->theme->fade_h)
-       {
-               patchbay->add_subwindow(fade = new VFadePatch(mwindow,
-                       this,
-                       x1 + x,
-                       y1 + y,
+       if( h - y1 >= mwindow->theme->fade_h ) {
+               patchbay->add_subwindow(fade = new VFadePatch(mwindow, this, x1+x, y1+y,
                        patchbay->get_w() - 10));
        }
        y1 += mwindow->theme->fade_h;
 
-       if(mode)
-       {
-               if(h - y1 < mwindow->theme->mode_h)
-               {
-                       delete mode;
-                       mode = 0;
-                       delete nudge;
-                       nudge = 0;
+       if( mode ) {
+               if( h - y1 < mwindow->theme->mode_h ) {
+                       delete mix;    mix = 0;
+                       delete mode;   mode = 0;
+                       delete nudge;  nudge = 0;
                }
-               else
-               {
+               else {
+                       if( mwindow->session->selected_zwindow >= 0 ) {
+                               int v = mwindow->mixer_track_active(track);
+                               mix->update(v);
+                       }
                        mode->update(mwindow->get_int_auto(this, AUTOMATION_MODE)->value);
                        nudge->update();
                }
        }
        else
-       if(h - y1 >= mwindow->theme->mode_h)
-       {
-               patchbay->add_subwindow(mode = new VModePatch(mwindow,
-                       this,
-                       x1 + x,
-                       y1 + y));
+       if( h - y1 >= mwindow->theme->mode_h ) {
+               patchbay->add_subwindow(mix = new VMixPatch(mwindow, this, x1+x, y1+y+5));
+               x1 += mix->get_w();
+               patchbay->add_subwindow(mode = new VModePatch(mwindow, this, x1+x, y1+y));
                mode->create_objects();
-               x1 += mode->get_w() + 10;
-               patchbay->add_subwindow(nudge = new NudgePatch(mwindow,
-                       this,
-                       x1 + x,
-                       y1 + y,
-                       patchbay->get_w() - x1 - 10));
+               x1 += mode->get_w();
+               patchbay->add_subwindow(nudge = new NudgePatch(mwindow, this, x1+x, y1+y,
+                       patchbay->get_w() - x1-x - 10));
        }
 
-
-
-
-
        y1 += mwindow->theme->mode_h;
-
        return y1;
 }
 
@@ -164,8 +141,7 @@ int VPatchGUI::update(int x, int y)
 
 void VPatchGUI::synchronize_fade(float value_change)
 {
-       if(fade && !change_source)
-       {
+       if( fade && !change_source ) {
                fade->update(Units::to_int64(fade->get_value() + value_change));
                fade->update_edl();
        }
@@ -203,8 +179,7 @@ float VFadePatch::update_edl()
 
 int VFadePatch::handle_event()
 {
-       if(shift_down())
-       {
+       if( shift_down() ) {
                update(100);
                set_tooltip(get_caption());
        }
@@ -213,7 +188,7 @@ int VFadePatch::handle_event()
 
        float change = update_edl();
 
-       if(patch->track->gang && patch->track->record)
+       if( patch->track->gang && patch->track->record )
                patch->patchbay->synchronize_faders(change, TRACK_VIDEO, patch->track);
 
        patch->change_source = 0;
@@ -223,8 +198,7 @@ int VFadePatch::handle_event()
        mwindow->restart_brender();
        mwindow->sync_parameters(CHANGE_PARAMS);
        mwindow->gui->lock_window("VFadePatch::handle_event");
-       if(mwindow->edl->session->auto_conf->autos[AUTOMATION_FADE])
-       {
+       if( mwindow->edl->session->auto_conf->autos[AUTOMATION_FADE] ) {
                mwindow->gui->draw_overlays(1);
        }
        return 1;
@@ -271,9 +245,6 @@ int VKeyFadeValue::handle_event()
 }
 
 
-
-
-
 VModePatch::VModePatch(MWindow *mwindow, VPatchGUI *patch, int x, int y)
  : BC_PopupMenu(x, y, patch->patchbay->mode_icons[0]->get_w() + 20,
        "", 1, mwindow->theme->get_image_set("mode_popup", 0), 10)
@@ -297,10 +268,10 @@ VModePatch::VModePatch(MWindow *mwindow, VPatchGUI *patch)
 int VModePatch::handle_event()
 {
 // Set menu items
-//     for(int i = 0; i < total_items(); i++)
+//     for( int i = 0; i < total_items(); i++ )
 //     {
 //             VModePatchItem *item = (VModePatchItem*)get_item(i);
-//             if(item->mode == mode)
+//             if( item->mode == mode )
 //                     item->set_checked(1);
 //             else
 //                     item->set_checked(0);
@@ -322,8 +293,7 @@ int VModePatch::handle_event()
 
        mwindow->sync_parameters(CHANGE_PARAMS);
 
-       if(mwindow->edl->session->auto_conf->autos[AUTOMATION_MODE])
-       {
+       if( mwindow->edl->session->auto_conf->autos[AUTOMATION_MODE] ) {
                mwindow->gui->draw_overlays(1);
        }
        mwindow->session->changes_made = 1;
@@ -377,8 +347,7 @@ void VModePatch::create_objects()
 void VModePatch::update(int mode)
 {
        set_icon(patch->patchbay->mode_to_icon(mode));
-       for(int i = 0; i < total_items(); i++)
-       {
+       for( int i = 0; i < total_items(); i++ ) {
                VModePatchItem *item = (VModePatchItem*)get_item(i);
                item->set_checked(item->mode == mode);
                VModePatchSubMenu *submenu = (VModePatchSubMenu *)item->get_submenu();
@@ -394,7 +363,7 @@ void VModePatch::update(int mode)
 
 const char* VModePatch::mode_to_text(int mode)
 {
-       switch(mode) {
+       switch( mode ) {
        case TRANSFER_NORMAL:           return _("Normal");
        case TRANSFER_ADDITION:         return _("Addition");
        case TRANSFER_SUBTRACT:         return _("Subtract");
@@ -436,7 +405,7 @@ VModePatchItem::VModePatchItem(VModePatch *popup, const char *text, int mode)
 {
        this->popup = popup;
        this->mode = mode;
-       if(this->mode == popup->mode) set_checked(1);
+       if( this->mode == popup->mode ) set_checked(1);
 }
 
 int VModePatchItem::handle_event()
@@ -463,7 +432,7 @@ VModeSubMenuItem::VModeSubMenuItem(VModePatchSubMenu *submenu, const char *text,
        this->submenu = submenu;
        this->mode = mode;
        VModePatch *popup = submenu->mode_item->popup;
-       if(this->mode == popup->mode) set_checked(1);
+       if( this->mode == popup->mode ) set_checked(1);
 }
 VModeSubMenuItem::~VModeSubMenuItem()
 {
@@ -500,4 +469,13 @@ int VKeyModePatch::handle_event()
 }
 
 
+VMixPatch::VMixPatch(MWindow *mwindow, VPatchGUI *patch, int x, int y)
+ : MixPatch(mwindow, patch, x, y)
+{
+       set_tooltip(_("Mixer"));
+}
+
+VMixPatch::~VMixPatch()
+{
+}
 
index ff6b98d35ace1476b96c74da74c4970b5a0d2c49..d071fb00d84fdb4983181040d55de96d237147df 100644 (file)
@@ -138,5 +138,11 @@ public:
        int handle_event();
 };
 
+class VMixPatch : public MixPatch
+{
+public:
+       VMixPatch(MWindow *mwindow, VPatchGUI *patch, int x, int y);
+       ~VMixPatch();
+};
 
 #endif
index f5fef954182d7565d35a78c40b13d24ada7e7584..0642dd81f05dbed51e7850ab08ff9adc830fe525 100644 (file)
@@ -879,7 +879,7 @@ void VWindowGUI::update_points()
 
 //printf("VWindowGUI::update_points 2\n");
        long pixel = (long)((double)edl->local_session->in_point /
-               edl->tracks->total_playable_length() *
+               edl->tracks->total_length() *
                (mwindow->theme->vtimebar_w -
                        2 *
                        mwindow->theme->in_point[0]->get_w())) +
@@ -931,7 +931,7 @@ void VWindowGUI::update_points()
 //printf("VWindowGUI::update_points 10\n");
 
        pixel = (long)((double)edl->local_session->out_point /
-               (edl->tracks->total_playable_length() + 0.5) *
+               (edl->tracks->total_length() + 0.5) *
                (mwindow->theme->vtimebar_w -
                        2 *
                        mwindow->theme->in_point[0]->get_w())) +
index 51971a8a49d189b7034b46cef81335c0f354f55e..424e9e50be5b79eabec3b4b90d1e73aa3daa12ab 100644 (file)
@@ -181,6 +181,7 @@ public:
        EDL* get_edl();
        void goto_start();
        void goto_end();
+       int is_vwindow() { return 1; }
 
        VWindowGUI *gui;
 };
diff --git a/cinelerra-5.1/cinelerra/zwindow.C b/cinelerra-5.1/cinelerra/zwindow.C
new file mode 100644 (file)
index 0000000..29a28a1
--- /dev/null
@@ -0,0 +1,261 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 1997-2012 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "bcdialog.h"
+#include "edl.h"
+#include "filexml.h"
+#include "language.h"
+#include "mainsession.h"
+#include "mwindow.h"
+#include "mwindowgui.h"
+#include "patchbay.h"
+#include "patchgui.h"
+#include "playbackengine.h"
+#include "renderengine.h"
+#include "timelinepane.h"
+#include "track.h"
+#include "transportque.h"
+#include "zwindow.h"
+#include "zwindowgui.h"
+
+Mixers::Mixers()
+{
+}
+
+Mixers::~Mixers()
+{
+       remove_all_objects();
+}
+
+Mixer *Mixers::new_mixer()
+{
+       int idx = 0;
+       for( int i=0; i<size(); ++i ) {
+               Mixer *mixer = get(i);
+               if( idx < mixer->idx ) idx = mixer->idx;
+       }
+       return append(new Mixer(idx+1));
+}
+
+Mixer *Mixers::get_mixer(int idx)
+{
+       for( int i=0; i<size(); ++i ) {
+               Mixer *mixer = get(i);
+               if( mixer->idx == idx ) return mixer;
+       }
+       return 0;
+}
+
+void Mixers::del_mixer(int idx)
+{
+       Mixer *mixer = get_mixer(idx);
+       if( mixer ) remove_object(mixer);
+}
+
+void Mixer::set_title(const char *tp)
+{
+       strncpy(title, tp, sizeof(title));
+       title[sizeof(title)-1] = 0;
+}
+
+void Mixers::save(FileXML *file)
+{
+       file->tag.set_title("MIXERS");
+       file->append_tag();
+       file->append_newline();
+       for( int i=0; i<size(); ++i ) {
+               Mixer *mixer = get(i);
+               mixer->save(file);
+       }
+       file->tag.set_title("/MIXERS");
+       file->append_tag();
+       file->append_newline();
+}
+
+int Mixers::load(FileXML *file)
+{
+       int result = 0;
+       while( !(result = file->read_tag()) ) {
+               if( file->tag.title_is("/MIXERS") ) break;
+               if( file->tag.title_is("MIXER") ) {
+                       Mixer *mixer = new_mixer();
+                       file->tag.get_property("TITLE", mixer->title);
+                       mixer->x = file->tag.get_property("X", mixer->x);
+                       mixer->y = file->tag.get_property("Y", mixer->y);
+                       mixer->w = file->tag.get_property("W", mixer->w);
+                       mixer->h = file->tag.get_property("H", mixer->h);
+                       mixer->load(file);
+               }
+       }
+       return 0;
+}
+
+void Mixers::copy_from(Mixers &that)
+{
+       remove_all_objects();
+       for( int i=0; i<that.size(); ++i ) {
+               Mixer *mixer = new_mixer();
+               mixer->copy_from(*that[i]);
+       }
+}
+
+void Mixer::save(FileXML *file)
+{
+       file->tag.set_title("MIXER");
+       file->tag.set_property("TITLE",title);
+       file->tag.set_property("X",x);
+       file->tag.set_property("Y",y);
+       file->tag.set_property("W",w);
+       file->tag.set_property("H",h);
+       file->append_tag();
+       file->append_newline();
+       for( int i=0; i<mixer_ids.size(); ++i ) {
+               file->tag.set_title("MIX");
+               file->tag.set_property("ID", mixer_ids[i]);
+               file->append_tag();
+               file->tag.set_title("/MIX");
+               file->append_tag();
+               file->append_newline();
+       }
+       file->tag.set_title("/MIXER");
+       file->append_tag();
+       file->append_newline();
+}
+
+Mixer::Mixer(int idx)
+{
+       this->idx = idx;
+       title[0] = 0;
+       x = y = 100 + idx*64;
+       w = 400;  h = 300;
+}
+void Mixer::reposition(int x, int y, int w, int h)
+{
+       this->x = x;  this->y = y;
+       this->w = w;  this->h = h;
+}
+
+int Mixer::load(FileXML *file)
+{
+       int result = 0;
+       while( !(result = file->read_tag()) ) {
+               if( file->tag.title_is("/MIXER") ) break;
+               if( file->tag.title_is("MIX") ) {
+                       mixer_ids.append(file->tag.get_property("ID", 0));
+               }
+       }
+       return 0;
+}
+
+void Mixer::copy_from(Mixer &that)
+{
+       mixer_ids.remove_all();
+       strncpy(title, that.title, sizeof(title));
+       title[sizeof(title)-1] = 0;
+       x = that.x;  y = that.y;
+       w = that.w;  h = that.h;
+       for( int i=0; i<that.mixer_ids.size(); ++i )
+               mixer_ids.append(that.mixer_ids[i]);
+}
+
+
+ZWindow::ZWindow(MWindow *mwindow)
+ : BC_DialogThread()
+{
+       this->mwindow = mwindow;
+       idx = -1;
+       edl = 0;
+       highlighted = 0;
+       title[0] = 0;
+       zgui = 0;
+}
+
+ZWindow::~ZWindow()
+{
+       close_window();
+       if( edl )
+               edl->remove_user();
+}
+
+BC_Window* ZWindow::new_gui()
+{
+       Mixer *mixer = mwindow->edl->mixers.get_mixer(idx);
+       zgui = new ZWindowGUI(mwindow, this, mixer);
+       zgui->create_objects();
+       return zgui;
+}
+
+void ZWindow::handle_done_event(int result)
+{
+}
+void ZWindow::handle_close_event(int result)
+{
+       zgui = 0;
+}
+
+void ZWindow::change_source(EDL *edl)
+{
+       if( this->edl && edl != this->edl )
+               this->edl->remove_user();
+       this->edl = edl;
+       if( edl != 0 ) {
+               zgui->playback_engine->que->send_command(CURRENT_FRAME, CHANGE_ALL, edl, 1);
+       }
+}
+
+void ZWindow::issue_command(int command, int wait_tracking,
+               int use_inout, int update_refresh, int toggle_audio)
+{
+       zgui->playback_engine->issue_command(edl, command,
+                       wait_tracking, use_inout, update_refresh, toggle_audio);
+}
+
+void ZWindow::update_mixer_ids()
+{
+       if( !running() ) return;
+       Mixer *mixer = mwindow->edl->mixers.get_mixer(idx);
+       if( !mixer ) return;
+       mixer->mixer_ids.remove_all();
+       PatchBay *patchbay = mwindow->gui->pane[0]->patchbay;
+       for( int i=0; i<patchbay->patches.size(); ++i ) {
+               PatchGUI *patchgui = patchbay->patches[i];
+               if( !patchgui->mixer ) continue;
+               int mixer_id = patchgui->track->get_mixer_id();
+               if( mixer->mixer_ids.number_of(mixer_id) >= 0 ) continue;
+               mixer->mixer_ids.append(mixer_id);
+       }
+}
+
+void ZWindow::set_title(const char *tp)
+{
+       char *cp = title, *ep = cp + sizeof(title)-1;
+       cp += snprintf(title, ep-cp, _("Mixer %d"), idx);
+       if( tp ) cp += snprintf(cp, ep-cp, ": %s", tp);
+       Mixer *mixer = mwindow->edl->mixers.get_mixer(idx);
+       if( mixer && tp != mixer->title ) mixer->set_title(tp);
+}
+
+void ZWindow::reposition(int x, int y, int w, int h)
+{
+       Mixer *mixer = mwindow->edl->mixers.get_mixer(idx);
+       if( mixer ) mixer->reposition(x, y, w, h);
+}
+
diff --git a/cinelerra-5.1/cinelerra/zwindow.h b/cinelerra-5.1/cinelerra/zwindow.h
new file mode 100644 (file)
index 0000000..9b53e42
--- /dev/null
@@ -0,0 +1,89 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 1997-2012 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef __ZWINDOW_H__
+#define __ZWINDOW_H__
+
+#include "arraylist.h"
+#include "bcdialog.h"
+#include "bcwindow.h"
+#include "edl.inc"
+#include "filexml.inc"
+#include "mwindow.inc"
+#include "playbackengine.inc"
+#include "renderengine.inc"
+#include "zwindowgui.inc"
+
+class Mixer {
+public:
+       int idx;
+       int x, y, w, h;
+       ArrayList<int> mixer_ids;
+       char title[BCSTRLEN];
+
+       Mixer(int idx);
+       void save(FileXML *file);
+       int load(FileXML *file);
+       void copy_from(Mixer &that);
+       void set_title(const char *tp);
+       void reposition(int x, int y, int w, int h);
+};
+
+class Mixers : public ArrayList<Mixer *>
+{
+public:
+       Mixers();
+       ~Mixers();
+       Mixer *new_mixer();
+       Mixer *get_mixer(int idx);
+       void del_mixer(int idx);
+       void save(FileXML *file);
+       int load(FileXML *file);
+       void copy_from(Mixers &that);
+};
+
+
+class ZWindow : public BC_DialogThread
+{
+public:
+       ZWindow(MWindow *mwindow);
+       ~ZWindow();
+
+       void handle_done_event(int result);
+       void handle_close_event(int result);
+       void change_source(EDL *edl);
+       void issue_command(int command, int wait_tracking,
+               int use_inout, int update_refresh, int toggle_audio);
+       void update_mixer_ids();
+       void set_title(const char *tp);
+       void reposition(int x, int y, int w, int h);
+
+       BC_Window *new_gui();
+       MWindow *mwindow;
+       ZWindowGUI *zgui;
+       EDL* edl;
+
+       int idx;
+       int highlighted;
+       char title[BCTEXTLEN];
+};
+
+#endif
diff --git a/cinelerra-5.1/cinelerra/zwindow.inc b/cinelerra-5.1/cinelerra/zwindow.inc
new file mode 100644 (file)
index 0000000..c7061e5
--- /dev/null
@@ -0,0 +1,29 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef __ZWINDOW_INC__
+#define __ZWINDOW_INC__
+
+class Mixer;
+class Mixers;
+class ZWindow;
+
+#endif
diff --git a/cinelerra-5.1/cinelerra/zwindowgui.C b/cinelerra-5.1/cinelerra/zwindowgui.C
new file mode 100644 (file)
index 0000000..46208af
--- /dev/null
@@ -0,0 +1,264 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 1997-2011 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#include "bcwindow.h"
+#include "canvas.h"
+#include "edl.h"
+#include "edlsession.h"
+#include "keys.h"
+#include "language.h"
+#include "localsession.h"
+#include "mainmenu.h"
+#include "mainsession.h"
+#include "mbuttons.h"
+#include "mwindow.h"
+#include "mwindowgui.h"
+#include "playbackengine.h"
+#include "playtransport.h"
+#include "renderengine.h"
+#include "theme.h"
+#include "tracks.h"
+#include "transportque.h"
+#include "zwindow.h"
+#include "zwindowgui.h"
+
+ZWindowGUI::ZWindowGUI(MWindow *mwindow, ZWindow *zwindow, Mixer *mixer)
+ : BC_Window(mixer->title, mixer->x, mixer->y, mixer->w, mixer->h,
+       100, 100, 1, 1, 0)
+{
+       this->mwindow = mwindow;
+       this->zwindow = zwindow;
+
+       canvas = 0;
+       playback_engine = 0;
+       highlighted = 0;
+}
+
+ZWindowGUI::~ZWindowGUI()
+{
+       delete playback_engine;
+       delete canvas;
+}
+
+void ZWindowGUI::create_objects()
+{
+       lock_window("ZWindowGUI::create_objects");
+
+       canvas = new ZWindowCanvas(mwindow, this, 10,10, get_w()-20,get_h()-20);
+       canvas->create_objects(mwindow->edl);
+       playback_engine = new PlaybackEngine(mwindow, canvas);
+       playback_engine->create_objects();
+
+       deactivate();
+       show_window();
+       unlock_window();
+}
+
+int ZWindowGUI::resize_event(int w, int h)
+{
+       canvas->reposition_window(0, 10,10, w-20,h-20);
+       zwindow->reposition(get_x(), get_y(), w, h);
+       BC_WindowBase::resize_event(w, h);
+       return 1;
+}
+
+int ZWindowGUI::translation_event()
+{
+       zwindow->reposition(get_x(), get_y(), get_w(), get_h());
+       return 0;
+}
+
+int ZWindowGUI::close_event()
+{
+       mwindow->del_mixer(zwindow);
+       set_done(0);
+       return 1;
+}
+
+int ZWindowGUI::keypress_event()
+{
+       int key = get_keypress();
+       if( key == 'w' || key == 'W' ) {
+               close_event();
+               return 1;
+       }
+       unlock_window();
+       int result = 1;
+       switch( key ) {
+       case 'f':
+               if( mwindow->session->zwindow_fullscreen )
+                       canvas->stop_fullscreen();
+               else
+                       canvas->start_fullscreen();
+               break;
+       case ESC:
+               if( mwindow->session->zwindow_fullscreen )
+                       canvas->stop_fullscreen();
+               break;
+       default:
+               mwindow->gui->lock_window("ZWindowGUI::keypress_event");
+               result = mwindow->gui->mbuttons->transport->do_keypress(key);
+               mwindow->gui->unlock_window();
+       }
+
+       lock_window("ZWindowGUI::keypress_event 1");
+       return result;
+}
+
+int ZWindowGUI::button_press_event()
+{
+       mwindow->select_zwindow(zwindow);
+       if( get_double_click() ) {
+               unlock_window();
+               mwindow->gui->lock_window("ZWindowGUI::button_press_event 0");
+               LocalSession *local_session = mwindow->edl->local_session;
+               double start = local_session->get_selectionstart(1);
+               double end = local_session->get_selectionend(1);
+               if( EQUIV(start, end) ) {
+                       start = mwindow->edl->tracks->total_recordable_length();
+                       if( start < 0 ) start = end;
+               }
+               if( (end-start) > 1e-4 ) {
+                       LocalSession *zlocal_session = zwindow->edl->local_session;
+                       zlocal_session->set_selectionstart(end);
+                       zlocal_session->set_selectionend(end);
+                       zlocal_session->set_inpoint(start);
+                       zlocal_session->set_outpoint(end);
+                       double orig_inpoint = local_session->get_inpoint();
+                       double orig_outpoint = local_session->get_outpoint();
+                       local_session->set_selectionstart(end);
+                       local_session->set_selectionend(end);
+                       local_session->set_inpoint(start);
+                       local_session->set_outpoint(end);
+                       mwindow->overwrite(zwindow->edl);
+                       local_session->set_inpoint(orig_inpoint);
+                       local_session->set_outpoint(orig_outpoint);
+                       mwindow->gui->update_timebar(1);
+               }
+               mwindow->gui->unlock_window();
+               lock_window("ZWindowGUI::button_press_event 1");
+       }
+       if( !canvas->get_canvas() ) return 0;
+       return canvas->button_press_event_base(canvas->get_canvas());
+}
+
+int ZWindowGUI::cursor_leave_event()
+{
+       if( !canvas->get_canvas() ) return 0;
+       return canvas->cursor_leave_event_base(canvas->get_canvas());
+}
+
+int ZWindowGUI::cursor_enter_event()
+{
+       if( !canvas->get_canvas() ) return 0;
+       return canvas->cursor_enter_event_base(canvas->get_canvas());
+}
+
+int ZWindowGUI::button_release_event()
+{
+       if( !canvas->get_canvas() ) return 0;
+       return canvas->button_release_event();
+}
+
+int ZWindowGUI::cursor_motion_event()
+{
+       BC_WindowBase *cvs = canvas->get_canvas();
+       if( !cvs ) return 0;
+       cvs->unhide_cursor();
+       return canvas->cursor_motion_event();
+}
+
+int ZWindowGUI::draw_overlays()
+{
+       BC_WindowBase *cvs = canvas->get_canvas();
+       if( !cvs || cvs->get_video_on() ) return 0;
+       if( highlighted != zwindow->highlighted ) {
+               highlighted = zwindow->highlighted;
+               cvs->set_color(WHITE);
+               cvs->set_inverse();
+               cvs->draw_rectangle(0, 0, cvs->get_w(), cvs->get_h());
+               cvs->draw_rectangle(1, 1, cvs->get_w() - 2, cvs->get_h() - 2);
+               cvs->set_opaque();
+       }
+       return 1;
+}
+
+ZWindowCanvas::ZWindowCanvas(MWindow *mwindow, ZWindowGUI *gui,
+               int x, int y, int w, int h)
+ : Canvas(mwindow, gui, x,y, w,h, 0,0,0)
+{
+       this->mwindow = mwindow;
+       this->gui = gui;
+}
+
+void ZWindowCanvas::close_source()
+{
+       gui->unlock_window();
+       gui->zwindow->zgui->playback_engine->interrupt_playback(1);
+       gui->lock_window("ZWindowCanvas::close_source");
+       EDL *edl = gui->zwindow->edl;
+       if( edl ) {
+               gui->zwindow->edl = 0;
+               edl->remove_user();
+       }
+}
+
+
+void ZWindowCanvas::draw_refresh(int flush)
+{
+       EDL *edl = gui->zwindow->edl;
+       BC_WindowBase *cvs = get_canvas();
+       int dirty = 0;
+
+       if( !cvs->get_video_on() ) {
+               cvs->clear_box(0, 0, cvs->get_w(), cvs->get_h());
+               gui->highlighted = 0;
+               dirty = 1;
+       }
+       if( !cvs->get_video_on() && refresh_frame && edl ) {
+               float in_x1, in_y1, in_x2, in_y2;
+               float out_x1, out_y1, out_x2, out_y2;
+               get_transfers(edl,
+                       in_x1, in_y1, in_x2, in_y2,
+                       out_x1, out_y1, out_x2, out_y2);
+               cvs->draw_vframe(refresh_frame,
+                       (int)out_x1, (int)out_y1, (int)(out_x2 - out_x1), (int)(out_y2 - out_y1),
+                       (int)in_x1, (int)in_y1, (int)(in_x2 - in_x1), (int)(in_y2 - in_y1), 0);
+               dirty = 1;
+       }
+       
+       if( gui->draw_overlays() )
+               dirty = 1;
+
+       if( dirty )
+               cvs->flash(flush);
+}
+
+int ZWindowCanvas::get_fullscreen()
+{
+       return mwindow->session->zwindow_fullscreen;
+}
+
+void ZWindowCanvas::set_fullscreen(int value)
+{
+       mwindow->session->zwindow_fullscreen = value;
+}
+
diff --git a/cinelerra-5.1/cinelerra/zwindowgui.h b/cinelerra-5.1/cinelerra/zwindowgui.h
new file mode 100644 (file)
index 0000000..ab658a9
--- /dev/null
@@ -0,0 +1,77 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef __ZWINDOWGUI_H__
+#define __ZWINDOWGUI_H__
+
+#include "bcwindow.h"
+#include "canvas.h"
+#include "mwindow.h"
+#include "renderengine.inc"
+
+class ZWindowGUI;
+class ZWindowCanvas;
+
+class ZWindowGUI : public BC_Window
+{
+public:
+       ZWindowGUI(MWindow *mwindow, ZWindow *vwindow, Mixer *mixer);
+       ~ZWindowGUI();
+
+       void create_objects();
+       int resize_event(int w, int h);
+       int translation_event();
+       int close_event();
+       int keypress_event();
+       int button_press_event();
+       int cursor_leave_event();
+       int cursor_enter_event();
+       int button_release_event();
+       int cursor_motion_event();
+       int select_window(int n);
+       int draw_overlays();
+
+       MWindow *mwindow;
+       ZWindow *zwindow;
+       ZWindowCanvas *canvas;
+
+       TransportCommand *command;
+       PlaybackEngine *playback_engine;
+       RenderEngine *render_engine;
+       int highlighted;
+};
+
+class ZWindowCanvas : public Canvas
+{
+public:
+       ZWindowCanvas(MWindow *mwindow, ZWindowGUI *gui,
+               int x, int y, int w, int h);
+
+       void draw_refresh(int flush = 1);
+       void close_source();
+       int get_fullscreen();
+       void set_fullscreen(int value);
+
+       MWindow *mwindow;
+       ZWindowGUI *gui;
+};
+
+#endif
diff --git a/cinelerra-5.1/cinelerra/zwindowgui.inc b/cinelerra-5.1/cinelerra/zwindowgui.inc
new file mode 100644 (file)
index 0000000..1fcb5d0
--- /dev/null
@@ -0,0 +1,27 @@
+
+/*
+ * CINELERRA
+ * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ */
+
+#ifndef __ZWINDOWGUI_INC__
+#define __ZWINDOWGUI_INC__
+
+class ZWindowGUI;
+
+#endif
index d8c60421006f0b87eecc6521ab8b2fd703d3895d..54a147966c96618fc4c96ceffe6739c73170baf8 100644 (file)
@@ -431,7 +431,7 @@ int BC_WindowBase::create_window(BC_WindowBase *parent_window, const char *title
        else
                this->display_name[0] = 0;
 
-       put_title(_(title));
+       put_title(title);
        if(bg_pixmap) shared_bg_pixmap = 1;
 
        subwindows = new BC_SubWindowList;
@@ -4148,7 +4148,7 @@ void BC_WindowBase::put_title(const char *text)
 void BC_WindowBase::set_title(const char *text, int utf8)
 {
 // utf8>0: wm + net_wm, utf8=0: wm only,  utf<0: net_wm only
-       put_title(_(text));
+       put_title(text);
        const unsigned char *wm_title = (const unsigned char *)title;
        int title_len = strlen((const char *)title);
        if( utf8 >= 0 ) {
diff --git a/cinelerra-5.1/picon/cinfinity/mixpatch.png b/cinelerra-5.1/picon/cinfinity/mixpatch.png
new file mode 100644 (file)
index 0000000..b5067ef
Binary files /dev/null and b/cinelerra-5.1/picon/cinfinity/mixpatch.png differ
diff --git a/cinelerra-5.1/picon/cinfinity/mixpatch_checked.png b/cinelerra-5.1/picon/cinfinity/mixpatch_checked.png
new file mode 100644 (file)
index 0000000..a71c5ce
Binary files /dev/null and b/cinelerra-5.1/picon/cinfinity/mixpatch_checked.png differ
diff --git a/cinelerra-5.1/picon/cinfinity/mixpatch_checkedhi.png b/cinelerra-5.1/picon/cinfinity/mixpatch_checkedhi.png
new file mode 100644 (file)
index 0000000..16b14a6
Binary files /dev/null and b/cinelerra-5.1/picon/cinfinity/mixpatch_checkedhi.png differ
diff --git a/cinelerra-5.1/picon/cinfinity/mixpatch_dn.png b/cinelerra-5.1/picon/cinfinity/mixpatch_dn.png
new file mode 100644 (file)
index 0000000..215bd1b
Binary files /dev/null and b/cinelerra-5.1/picon/cinfinity/mixpatch_dn.png differ
diff --git a/cinelerra-5.1/picon/cinfinity/mixpatch_hi.png b/cinelerra-5.1/picon/cinfinity/mixpatch_hi.png
new file mode 100644 (file)
index 0000000..4d8c09b
Binary files /dev/null and b/cinelerra-5.1/picon/cinfinity/mixpatch_hi.png differ
diff --git a/cinelerra-5.1/picon/cinfinity/mixpatch_up.png b/cinelerra-5.1/picon/cinfinity/mixpatch_up.png
new file mode 100644 (file)
index 0000000..6a1de5e
Binary files /dev/null and b/cinelerra-5.1/picon/cinfinity/mixpatch_up.png differ