add master/armed_gang track operations, tweak appearanceprefs layout, fix vicon video...
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / mwindow.C
index 93e0a457aba68912903ef05b7d5fe21e10700cc1..c4e7a7cbf1fe22118a12034cffddcfe47ed2c114 100644 (file)
@@ -243,6 +243,7 @@ MWindow::MWindow()
        in_destructor = 0;
        speed_edl = 0;
        beeper = 0;
+       redraw_tracks = 0;
        shuttle = 0;
        wintv = 0;
        x10tv = 0;
@@ -265,9 +266,10 @@ MWindow::~MWindow()
 #ifdef HAVE_DVB
        gui->channel_info->stop();
 #endif
-       delete beeper;
-       delete create_bd;       create_bd = 0;
-       delete create_dvd;      create_dvd = 0;
+       delete beeper;          beeper = 0;
+       delete redraw_tracks;   redraw_tracks = 0;
+       delete create_bd;       create_bd = 0;
+       delete create_dvd;      create_dvd = 0;
 #ifdef HAVE_SHUTTLE
        delete shuttle;         shuttle = 0;
 #endif
@@ -301,6 +303,7 @@ MWindow::~MWindow()
        gui->del_keyboard_listener(
                (int (BC_WindowBase::*)(BC_WindowBase *))
                &MWindowGUI::keyboard_listener);
+       reset_caches();
 #if 0
 // release the hounds
        if( awindow && awindow->gui ) awindow->gui->close(0);
@@ -329,7 +332,6 @@ MWindow::~MWindow()
        gui->close(0);
        join();
 #endif
-       reset_caches();
        dead_plugins->remove_all_objects();
 // must delete theme before destroying plugindb
 //  theme destructor will be deleted by delete_plugins
@@ -1210,10 +1212,23 @@ ZWindow *MWindow::get_mixer(Mixer *&mixer)
        return zwindow;
 }
 
-void MWindow::del_mixer(ZWindow *zwindow)
+ZWindow *MWindow::get_mixer(int idx)
+{
+       ZWindow *zwindow = 0;
+       zwindows_lock->lock("MWindow::get_mixer");
+       for( int i=0; !zwindow && i<zwindows.size(); ++i ) {
+               ZWindow *zwdw = zwindows[i];
+               if( !zwdw->running() ) continue;
+               if( zwdw->idx != idx ) continue;
+               zwindow = zwindows[i];
+       }
+       zwindows_lock->unlock();
+       return zwindow;
+}
+
+void MWindow::close_mixer(ZWindow *zwindow)
 {
-       zwindows_lock->lock("MWindow::del_mixer 0");
-       edl->mixers.del_mixer(zwindow->idx);
+       zwindows_lock->lock("MWindow::close_mixer 0");
        if( session->selected_zwindow >= 0 ) {
                int i = zwindows.number_of(zwindow);
                if( i >= 0 && i < session->selected_zwindow )
@@ -1222,7 +1237,7 @@ void MWindow::del_mixer(ZWindow *zwindow)
                        session->selected_zwindow = -1;
        }
        zwindows_lock->unlock();
-       gui->lock_window("MWindow::del_mixer 1");
+       gui->lock_window("MWindow::close_mixer 1");
        gui->update_mixers(0, -1);
        gui->unlock_window();
 }
@@ -1297,11 +1312,11 @@ void MWindow::handle_mixers(EDL *edl, int command, int wait_tracking,
                        k = mixer->mixer_ids.size();
                        while( --k >= 0 && track->get_mixer_id() != mixer->mixer_ids[k] );
                        if( k >= 0 ) {
-                               track->record = 1;
+                               track->armed = 1;
                                track->play = track->data_type == TRACK_VIDEO ? 1 : 0;
                        }
                        else
-                               track->record = track->play = 0;
+                               track->armed = track->play = 0;
                }
                zwindow->change_source(mixer_edl);
                zwindow->handle_mixer(command, 0,
@@ -1356,7 +1371,7 @@ ZWindow *MWindow::create_mixer(Indexable *indexable, double position)
        Mixer *mixer = 0;
        ZWindow *zwindow = get_mixer(mixer);
        while( track ) {
-               track->play = track->record = 0;
+               track->play = track->armed = 0;
                if( track->data_type == TRACK_VIDEO ) {
                        sprintf(track->title, _("Mixer %d"), zwindow->idx);
                }
@@ -1499,6 +1514,14 @@ void MWindow::tile_mixers()
        }
 }
 
+void MWindow::set_gang_tracks(int v)
+{
+       edl->session->gang_tracks = v;
+       gui->update(1, 1, 0, 0, 1, 0, 0);
+       gui->flush();
+}
+
+
 void MWindow::init_cache()
 {
        audio_cache = new CICache(preferences);
@@ -1769,7 +1792,7 @@ int MWindow::put_commercial()
        //check it
        for(Track *track=tracks->first; track && !errmsg; track=track->next) {
                if( track->data_type != TRACK_VIDEO ) continue;
-               if( !track->record ) continue;
+               if( !track->armed ) continue;
                if( count > 0 ) { errmsg = _("multiple video tracks"); break; }
                ++count;
                int64_t units_start = track->to_units(start,0);
@@ -1789,7 +1812,7 @@ int MWindow::put_commercial()
        //run it
        for(Track *track=tracks->first; track && !errmsg; track=track->next) {
                if( track->data_type != TRACK_VIDEO ) continue;
-               if( !track->record ) continue;
+               if( !track->armed ) continue;
                int64_t units_start = track->to_units(start,0);
                int64_t units_end = track->to_units(end,0);
                Edits *edits = track->edits;
@@ -2974,6 +2997,7 @@ void MWindow::show_lwindow()
 
 void MWindow::restore_windows()
 {
+       gui->unlock_window();
        if( !session->show_vwindow ) {
                for( int i=0, n=vwindows.size(); i<n; ++i ) {
                        VWindow *vwindow = vwindows[i];
@@ -3018,6 +3042,7 @@ void MWindow::restore_windows()
        else if( session->show_lwindow && lwindow->gui->is_hidden() )
                show_lwindow();
 
+       gui->lock_window("MWindow::restore_windows");
        gui->focus();
 }
 
@@ -3081,7 +3106,6 @@ void MWindow::set_auto_keyframes(int value)
        gui->mbuttons->edit_panel->keyframe->update(value);
        gui->flush();
        cwindow->gui->lock_window("MWindow::set_auto_keyframes");
-       cwindow->gui->edit_panel->keyframe->update(value);
        cwindow->gui->flush();
        cwindow->gui->unlock_window();
 }
@@ -3092,7 +3116,6 @@ void MWindow::set_span_keyframes(int value)
        gui->mbuttons->edit_panel->span_keyframe->update(value);
        gui->flush();
        cwindow->gui->lock_window("MWindow::set_span_keyframes");
-       cwindow->gui->edit_panel->span_keyframe->update(value);
        cwindow->gui->flush();
        cwindow->gui->unlock_window();
 }
@@ -3752,6 +3775,7 @@ void MWindow::update_project(int load_mode)
 
                for( int i=0; i<edl->mixers.size(); ++i ) {
                        Mixer *mixer = edl->mixers[i];
+                       if( !mixer->show ) continue;
                        ZWindow *zwindow = get_mixer(mixer);
                        zwindow->set_title(mixer->title);
                        zwindow->start();
@@ -3781,7 +3805,7 @@ void MWindow::update_project(int load_mode)
        if(debug) PRINT_TRACE
 }
 
-void MWindow::stack_push(EDL *new_edl, Indexable *idxbl)
+void MWindow::stack_push(EDL *new_edl, Indexable *idxbl, Edit *edit)
 {
        int got_indexes = 0;
        for( int i=0; i<new_edl->nested_edls.size(); ++i ) {
@@ -3807,7 +3831,9 @@ void MWindow::stack_push(EDL *new_edl, Indexable *idxbl)
                undo_before();
                StackItem &item = stack.append();
                item.edl = edl;
+               item.edit = edit;
                item.new_edl = new_edl;
+               item.duration = new_edl->tracks->total_length();
                item.undo = undo;
                item.idxbl = idxbl;
                item.mtime = 0;
@@ -3840,6 +3866,17 @@ void MWindow::stack_pop()
 // session edl replaced, overwrite and save clip data
        if( item.new_edl != edl )
                item.new_edl->overwrite_clip(edl);
+       Edit *edit = item.edit;
+// resize the referring edit if the edl duration changed
+       if( edit ) {
+               double duration = item.new_edl->tracks->total_length();
+               double dt = duration - item.duration;
+               if( fabs(dt) > 1e-4 ) {
+                       int64_t du = edit->track->to_units(dt,0);
+                       if( (edit->length+=du) < 0 )
+                               edit->length = 0;
+               }
+       }
        edl->remove_user();
        edl = item.edl;
        delete undo;
@@ -3849,6 +3886,7 @@ void MWindow::stack_pop()
        stack.remove();
        if( idxbl ) {
                gui->unlock_window();
+               gui->resource_thread->close_indexable(idxbl);
                remove_from_caches(idxbl);
                remove_indexfile(idxbl);
                mainindexes->add_indexable(idxbl);
@@ -3952,6 +3990,7 @@ void MWindow::clip_to_media()
                return;
        }
        undo_before();
+       awindow->gui->stop_vicon_drawing();
        int clips_total = session->drag_clips->total;
        for( int i=0; i<clips_total; ++i ) {
                EDL *clip = session->drag_clips->values[i];
@@ -4428,6 +4467,7 @@ int MWindow::create_aspect_ratio(float &w, float &h, int width, int height)
 
 void MWindow::reset_caches()
 {
+       awindow->gui->stop_vicon_drawing();
        frame_cache->remove_all();
        wave_cache->remove_all();
        audio_cache->remove_all();
@@ -4451,6 +4491,7 @@ void MWindow::reset_caches()
 
 void MWindow::remove_from_caches(Indexable *idxbl)
 {
+       awindow->gui->stop_vicon_drawing();
        frame_cache->remove_item(idxbl);
        wave_cache->remove_item(idxbl);
        if( gui->render_engine &&
@@ -4458,11 +4499,7 @@ void MWindow::remove_from_caches(Indexable *idxbl)
                delete gui->render_engine;
                gui->render_engine = 0;
        }
-       if( gui->resource_thread->render_engine_id == idxbl->id ) {
-               gui->resource_thread->render_engine_id = -1;
-               delete gui->resource_thread->render_engine;
-               gui->resource_thread->render_engine = 0;
-       }
+       gui->resource_thread->close_indexable(idxbl);
        if( !idxbl->is_asset ) return;
        Asset *asset = (Asset *)idxbl;
        audio_cache->delete_entry(asset);
@@ -4488,12 +4525,13 @@ void MWindow::remove_from_caches(Indexable *idxbl)
                if( zwindow->zgui->playback_engine->video_cache )
                        zwindow->zgui->playback_engine->video_cache->delete_entry(asset);
        }
+       awindow->gui->start_vicon_drawing();
 }
 
 void MWindow::remove_assets_from_project(int push_undo, int redraw, int delete_indexes,
                ArrayList<Indexable*> *drag_assets, ArrayList<EDL*> *drag_clips)
 {
-       awindow->gui->close_view_popup();
+       awindow->gui->stop_vicon_drawing();
 
 // Remove from VWindow.
        if( drag_clips ) {
@@ -4648,6 +4686,14 @@ void MWindow::dump_exe(FILE *fp)
        fprintf(fp, "\n");
 }
 
+void MWindow::dump_caches(FILE *fp)
+{
+       fprintf(fp, "audio cache: ");
+       audio_cache->dump(fp);
+       fprintf(fp, "video cache: ");
+       video_cache->dump(fp);
+}
+
 void MWindow::trap_hook(FILE *fp, void *vp)
 {
        MWindow *mwindow = (MWindow *)vp;
@@ -4659,6 +4705,8 @@ void MWindow::trap_hook(FILE *fp, void *vp)
        mwindow->dump_undo(fp);
        fprintf(fp, "\nEXE: %s\n", AboutPrefs::build_timestamp);
        mwindow->dump_exe(fp);
+       fprintf(fp, "\nCACHES:\n");
+       mwindow->dump_caches(fp);
 }
 
 
@@ -5085,13 +5133,42 @@ PatchGUI *MWindow::get_patchgui(Track *track)
         return patchgui;
 }
 
-int MWindow::get_cpus()
+int MWindow::get_cpus(int out_w, int out_h)
 {
-       int out_w = edl->session->output_w;
-       int out_h = edl->session->output_h;
+       if( !out_w ) out_w = edl->session->output_w;
+       if( !out_h ) out_h = edl->session->output_h;
        int cpus = out_w*out_h/0x80000 + 1;
        if( cpus > preferences->processors )
                cpus = preferences->processors;
        return cpus;
 }
+int MWindow::get_cpus()
+{
+       return get_cpus(edl->session->output_w, edl->session->output_h);
+}
+
+void MWindow::draw_trackmovement()
+{
+       if( !redraw_tracks )
+               redraw_tracks = new DrawTrackMovement(this);
+       redraw_tracks->start();
+}
+
+DrawTrackMovement::DrawTrackMovement(MWindow *mwindow)
+ : Thread(1, 0, 0)
+{
+       this->mwindow = mwindow;
+}
+DrawTrackMovement::~DrawTrackMovement()
+{
+       join();
+}
+
+void DrawTrackMovement::run()
+{
+       mwindow->gui->lock_window("DrawTrackMovement::run");
+       mwindow->edl->tracks->update_y_pixels(mwindow->theme);
+       mwindow->gui->draw_trackmovement();
+       mwindow->gui->unlock_window();
+}