no longer need ffmpeg patch0 which was for Termux
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / mwindowgui.C
index 0033b268950d11eec7288d1a679db956bcde672a..3b939df5bb6fe3459c093d3835a83bb02a01e3a0 100644 (file)
@@ -56,6 +56,7 @@
 #include "pluginpopup.h"
 #include "pluginset.h"
 #include "preferences.h"
+#include "proxy.h"
 #include "record.h"
 #include "recordgui.h"
 #include "renderengine.h"
@@ -127,6 +128,8 @@ MWindowGUI::MWindowGUI(MWindow *mwindow)
        cwindow_remote_handler = 0;
        record_remote_handler = 0;
        android_control = 0;
+// *** CONTEXT_HELP ***
+       context_help_set_keyword("Program Window");
 }
 
 
@@ -159,7 +162,7 @@ void MWindowGUI::create_objects()
        lock_window("MWindowGUI::create_objects");
        const int debug = 0;
 
-       resource_thread = new ResourceThread(mwindow, this);
+       resource_thread = new ResourceThread(mwindow);
        resource_thread->create_objects();
 
 
@@ -186,6 +189,12 @@ void MWindowGUI::create_objects()
        }
 #endif
        mwindow->reset_android_remote();
+       if( !cwindow_remote_handler )
+               cwindow_remote_handler = (RemoteHandler*)
+                       new CWindowKeyEvHandler(mwindow->gui->remote_control);
+       if( !record_remote_handler )
+               record_remote_handler = (RemoteHandler*)
+                       new RecordKeyEvHandler(mwindow->gui->remote_control);
        if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
 
        int x1 = get_w() - MainShBtns::calculate_w(-1, 0, -1) - xS(5);
@@ -293,14 +302,14 @@ void MWindowGUI::redraw_time_dependancies()
 int MWindowGUI::focus_in_event()
 {
        for(int i = 0; i < TOTAL_PANES; i++)
-               if(pane[i]) pane[i]->cursor->focus_in_event();
+               if(pane[i] && pane[i]->cursor) pane[i]->cursor->focus_in_event();
        return 1;
 }
 
 int MWindowGUI::focus_out_event()
 {
        for(int i = 0; i < TOTAL_PANES; i++)
-               if(pane[i]) pane[i]->cursor->focus_out_event();
+               if(pane[i] && pane[i]->cursor) pane[i]->cursor->focus_out_event();
        return 1;
 }
 
@@ -310,7 +319,7 @@ int MWindowGUI::resize_event(int w, int h)
 //printf("MWindowGUI::resize_event %d\n", __LINE__);
        mwindow->session->mwindow_w = w;
        mwindow->session->mwindow_h = h;
-       int x1 = get_w() - MainShBtns::calculate_w(-1, 0, -1) - xS(5);
+       int x1 = w - MainShBtns::calculate_w(-1, 0, -1) - xS(5);
        mainshbtns->reposition_window(x1, -1);
        int x2 = x1 - mwindow->theme->stack_button_w - xS(5);
        stack_button->reposition_window(x2, stack_button->get_y());
@@ -506,7 +515,7 @@ void MWindowGUI::deactivate_timeline()
 {
        for(int i = 0; i < TOTAL_PANES; i++)
        {
-               if(pane[i])
+               if(pane[i] && pane[i]->canvas)
                {
                        pane[i]->canvas->deactivate();
                }
@@ -528,7 +537,7 @@ void MWindowGUI::draw_overlays(int flash_it)
 {
        for(int i = 0; i < TOTAL_PANES; i++)
        {
-               if(pane[i])
+               if(pane[i] && pane[i]->canvas)
                {
                        pane[i]->canvas->draw_overlays();
                        if(flash_it) pane[i]->canvas->flash();
@@ -572,10 +581,9 @@ void MWindowGUI::update_patchbay()
 
 void MWindowGUI::update_proxy_toggle()
 {
-       int value = mwindow->edl->session->proxy_scale == 1 ? 1 : 0;
+       int value = mwindow->edl->session->proxy_state == PROXY_ACTIVE ? 0 : 1;
        proxy_toggle->set_value(value);
-       if( mwindow->edl->session->proxy_scale == 1 &&
-           mwindow->edl->session->proxy_disabled_scale == 1 )
+       if( mwindow->edl->session->proxy_state == PROXY_INACTIVE )
                proxy_toggle->hide();
        else
                proxy_toggle->show();
@@ -585,7 +593,7 @@ void MWindowGUI::update_plugintoggles()
 {
        for(int i = 0; i < TOTAL_PANES; i++)
        {
-               if(pane[i])
+               if(pane[i] && pane[i]->canvas)
                {
                        pane[i]->canvas->refresh_plugintoggles();
                }
@@ -597,7 +605,7 @@ void MWindowGUI::draw_indexes(Indexable *indexable)
 {
        for(int i = 0; i < TOTAL_PANES; i++)
        {
-               if(pane[i])
+               if(pane[i] && pane[i]->canvas)
                {
                        pane[i]->canvas->draw_indexes(indexable);
                }
@@ -607,8 +615,11 @@ void MWindowGUI::draw_indexes(Indexable *indexable)
 void MWindowGUI::draw_canvas(int redraw, int hide_cursor)
 {
        resource_thread->stop_draw(0);
-
-       int mode = redraw ? FORCE_REDRAW : NORMAL_DRAW;
+       int mode = NORMAL_DRAW;
+       if( redraw ) {
+               mode = FORCE_REDRAW;
+               resource_pixmaps.remove_all_objects();
+       }
        for(int i = 0; i < TOTAL_PANES; i++) {
                if( pane[i] )
                        pane[i]->canvas->draw(mode, hide_cursor);
@@ -621,7 +632,7 @@ void MWindowGUI::flash_canvas(int flush)
 {
        for(int i = 0; i < TOTAL_PANES; i++)
        {
-               if(pane[i])
+               if(pane[i] && pane[i]->canvas)
                {
                        pane[i]->canvas->flash(flush);
                }
@@ -640,7 +651,7 @@ void MWindowGUI::draw_cursor(int do_plugintoggles)
 {
        for(int i = 0; i < TOTAL_PANES; i++)
        {
-               if(pane[i])
+               if(pane[i] && pane[i]->cursor)
                {
                        pane[i]->cursor->draw(do_plugintoggles);
                }
@@ -651,7 +662,7 @@ void MWindowGUI::show_cursor(int do_plugintoggles)
 {
        for(int i = 0; i < TOTAL_PANES; i++)
        {
-               if(pane[i])
+               if(pane[i] && pane[i]->cursor)
                {
                        pane[i]->cursor->show(do_plugintoggles);
                }
@@ -662,7 +673,7 @@ void MWindowGUI::hide_cursor(int do_plugintoggles)
 {
        for(int i = 0; i < TOTAL_PANES; i++)
        {
-               if(pane[i])
+               if(pane[i] && pane[i]->cursor)
                {
                        pane[i]->cursor->hide(do_plugintoggles);
                }
@@ -673,7 +684,7 @@ void MWindowGUI::update_cursor()
 {
        for(int i = 0; i < TOTAL_PANES; i++)
        {
-               if(pane[i])
+               if(pane[i] && pane[i]->cursor)
                {
                        pane[i]->cursor->update();
                }
@@ -684,7 +695,7 @@ void MWindowGUI::set_playing_back(int value)
 {
        for(int i = 0; i < TOTAL_PANES; i++)
        {
-               if(pane[i])
+               if(pane[i] && pane[i]->cursor)
                {
                        pane[i]->cursor->playing_back = value;
                }
@@ -740,7 +751,7 @@ void MWindowGUI::set_editing_mode(int flush)
 {
        for(int i = 0; i < TOTAL_PANES; i++)
        {
-               if(pane[i])
+               if(pane[i] && pane[i]->canvas)
                {
                        pane[i]->canvas->update_cursor(flush);
                }
@@ -776,6 +787,9 @@ void MWindowGUI::update(int scrollbars,
        if( do_canvas != NO_DRAW && do_canvas != IGNORE_THREAD )
                resource_thread->stop_draw(1);
 
+       if( do_canvas == FORCE_REDRAW )
+               resource_pixmaps.remove_all_objects();
+
        for(int i = 0; i < TOTAL_PANES; i++)
        {
                if(pane[i]) pane[i]->update(scrollbars,
@@ -876,11 +890,9 @@ int MWindowGUI::drag_motion()
 
        for(int i = 0; i < TOTAL_PANES; i++)
        {
-               if(pane[i]) pane[i]->canvas->drag_motion(
-                       &over_track,
-                       &over_edit,
-                       &over_pluginset,
-                       &over_plugin);
+               if(pane[i] && pane[i]->canvas)
+                       pane[i]->canvas->drag_motion(&over_track, &over_edit,
+                                       &over_pluginset, &over_plugin);
        }
 
        if(mwindow->session->track_highlighted != over_track)
@@ -937,8 +949,8 @@ int MWindowGUI::drag_stop()
 
        for(int i = 0; i < TOTAL_PANES; i++)
        {
-               if(pane[i]) result |= pane[i]->canvas->drag_stop(
-                       &redraw);
+               if(pane[i] && pane[i]->canvas)
+                       result |= pane[i]->canvas->drag_stop(&redraw);
        }
        mwindow->edl->optimize();
 
@@ -1032,6 +1044,7 @@ void MWindowGUI::default_positions()
        mwindow->cwindow->gui->unlock_window();
        mwindow->awindow->gui->unlock_window();
 //printf("MWindowGUI::default_positions 2\n");
+       mwindow->tile_mixers();
 }
 
 
@@ -1042,7 +1055,8 @@ int MWindowGUI::repeat_event(int64_t duration)
        int result = 0;
        for(int i = 0; i < TOTAL_PANES; i++)
        {
-               if(pane[i]) result = pane[i]->cursor->repeat_event(duration);
+               if(pane[i] && pane[i]->cursor)
+                       result = pane[i]->cursor->repeat_event(duration);
        }
        return result;
 }
@@ -1073,24 +1087,42 @@ int MWindowGUI::keypress_event()
        if( result ) return result;
 
        Track *this_track = 0, *first_track = 0;
-       int collapse = 0, packed = 0, overwrite = 0, plugins = 0;
+       int packed = 0, overwrite = 0, plugins = 0;
        double position = 0;
 
        switch( get_keypress() ) {
        case 'A':
-               if( !ctrl_down() || !shift_down() || alt_down() ) break;
-               mwindow->edl->tracks->clear_selected_edits();
-               draw_overlays(1);
+               if( !alt_down() ) {
+                       if( !ctrl_down() || !shift_down() ) break;
+                       mwindow->edl->tracks->clear_selected_edits();
+                       draw_overlays(1);
+                       result = 1;
+                       break;
+               } // fall thru
+       case 'a':
+               if( !alt_down() ) break;
+               stop_transport("MWindowGUI::keypress_event 1");
+               mwindow->nearest_auto_keyframe(shift_down(),
+                       !ctrl_down() ? PLAY_FORWARD : PLAY_REVERSE);
                result = 1;
                break;
+
+       case '\'':
+               if( ctrl_down() && alt_down() ) {
+                       mwindow->select_edits(1);
+                       result = 1;
+               }
+               break;
+
        case 'e':
+               if( ctrl_down() || alt_down() ) break;
                mwindow->toggle_editing_mode();
                result = 1;
                break;
 
        case 'k': case 'K':
                if( alt_down() ) break;
-               stop_transport("MWindowGUI::keypress_event 1");
+               stop_transport("MWindowGUI::keypress_event 2");
                mwindow->nearest_plugin_keyframe(shift_down(),
                        !ctrl_down() ? PLAY_FORWARD : PLAY_REVERSE);
                result = 1;
@@ -1134,17 +1166,29 @@ int MWindowGUI::keypress_event()
                result = 1;
                break;
        case 'M':
-               collapse = 1;
+               mwindow->cut_selected_edits(0, 1);
+               result = 1;
+               break;
        case BACKSPACE:
        case 'm':
-               mwindow->cut_selected_edits(0, collapse);
+               mwindow->cut_selected_edits(0, 0);
                result = 1;
                break;
        case 'z':
-               collapse = 1;
+               if( !alt_down() ) {
+                       // z and ctrl-z both are undo, z mainmenu item
+                       if( mwindow->session->current_operation == NO_OPERATION )
+                               mwindow->undo_entry(this);
+                       result = 1;
+               }
+               else if( ctrl_down() ) {
+                       mwindow->cut_selected_edits(1, 1);
+                       result = 1;
+               }
+               break;
        case 'x':
                if( !ctrl_down() || alt_down() ) break;
-               mwindow->cut_selected_edits(1, collapse);
+               mwindow->cut_selected_edits(1, 0);
                result = 1;
                break;
 
@@ -1192,6 +1236,32 @@ int MWindowGUI::keypress_event()
                }
                break;
 
+       case '!':
+               if( !ctrl_down() || !shift_down() ) break;
+               {
+                       if( mwindow->session->current_operation != NO_OPERATION ) return 1;
+                       first_track = mwindow->edl->tracks->first;
+                       double start = mwindow->edl->local_session->get_selectionstart();
+                       int64_t pos = first_track->to_units(start, 0);
+                       Edit *edit=first_track->edits->editof(pos, PLAY_FORWARD, 0);
+                       if( !edit || !edit->asset ) return 1;
+                       Asset *asset = edit->asset;
+                       double timecode = asset->timecode != -2 ? asset->timecode :
+                               FFMPEG::get_timecode(asset->path,
+                                       edit->track->data_type, edit->channel,
+                                       mwindow->edl->session->frame_rate);
+                       asset->timecode = timecode;
+                       if( timecode >= 0 ) {
+                               int64_t pos = edit->startproject + edit->startsource;
+                               double position = edit->track->from_units(pos);
+                               mwindow->set_timecode_offset(timecode - position);
+                       }
+                       else
+                               mwindow->set_timecode_offset(0);
+               }
+               result = 1;
+               break;
+
        case UP:
                if( ctrl_down() && !alt_down() )
                        mwindow->expand_y();
@@ -1240,18 +1310,18 @@ int MWindowGUI::keypress_event()
                        if( (this_track = pane[i]->over_patchbay()) != 0 ) break;
                }
 
-               if( get_keypress() == TAB ) { // Switch the record button
+               if( get_keypress() == TAB ) { // Switch the armed button
                        if( this_track )
-                               this_track->record = !this_track->record ? 1 : 0;
+                               this_track->armed = !this_track->armed ? 1 : 0;
                }
                else {
                        int total_selected = mwindow->edl->tracks->total_of(Tracks::RECORD);
                        // all selected if nothing previously selected or
                        // if this patch was previously the only one selected and armed
                        int selected = !total_selected || (total_selected == 1 &&
-                               this_track && this_track->record ) ? 1 : 0;
+                               this_track && this_track->armed ) ? 1 : 0;
                        mwindow->edl->tracks->select_all(Tracks::RECORD, selected);
-                       if( !selected && this_track ) this_track->record = 1;
+                       if( !selected && this_track ) this_track->armed = 1;
                }
 
                update(0, NORMAL_DRAW, 0, 0, 1, 0, 1);
@@ -1271,6 +1341,9 @@ int MWindowGUI::keypress_event()
        if(result)
                cursor_motion_event();
 
+       if(!result)
+               result = context_help_check_and_show();
+
        return result;
 }
 
@@ -1793,6 +1866,7 @@ void MWindowGUI::delete_y_pane(int cursor_y)
 
 void MWindowGUI::stop_pane_drag()
 {
+       if( !dragging_pane ) return;
        dragging_pane = 0;
        resource_thread->stop_draw(0);
 
@@ -2267,6 +2341,19 @@ void MWindowGUI::stop_transport(const char *lock_msg)
        }
 }
 
+void MWindowGUI::close_keyvalue_popup()
+{
+       if( !keyvalue_popup ) return;
+       delete keyvalue_popup;
+       keyvalue_popup = 0;
+}
+
+void MWindowGUI::open_keyvalue_popup(BC_SubWindow *popup)
+{
+       close_keyvalue_popup();
+       keyvalue_popup = popup;
+}
+
 PaneButton::PaneButton(MWindow *mwindow, int x, int y)
  : BC_Button(x, y, mwindow->theme->get_image_set("pane"))
 {
@@ -2315,6 +2402,8 @@ FFMpegToggle::FFMpegToggle(MWindow *mwindow, MButtons *mbuttons, int x, int y)
        this->mwindow = mwindow;
        this->mbuttons = mbuttons;
        set_tooltip(get_value() ? FFMPEG_EARLY_TIP : FFMPEG_LATE_TIP);
+// *** CONTEXT_HELP ***
+       context_help_set_keyword("FFmpeg Early Probe Explanation");
 }
 
 FFMpegToggle::~FFMpegToggle()
@@ -2339,6 +2428,8 @@ StackButton::StackButton(MWindow *mwindow, int x, int y)
 {
        this->mwindow = mwindow;
        set_tooltip(_("Close EDL"));
+// *** CONTEXT_HELP ***
+       context_help_set_keyword("OpenEDL");
 }
 
 int StackButton::handle_event()
@@ -2362,13 +2453,15 @@ ProxyToggle::ProxyToggle(MWindow *mwindow, MButtons *mbuttons, int x, int y)
  : BC_Toggle(x, y, ( !mwindow->edl->session->proxy_use_scaler ?
                        mwindow->theme->proxy_p_toggle :
                        mwindow->theme->proxy_s_toggle ),
-               mwindow->edl->session->proxy_disabled_scale != 1)
+               mwindow->edl->session->proxy_state == PROXY_DISABLED)
 {
        this->mwindow = mwindow;
        this->mbuttons = mbuttons;
        scaler_images = mwindow->edl->session->proxy_use_scaler;
-       set_tooltip(mwindow->edl->session->proxy_disabled_scale==1 ?
+       set_tooltip(mwindow->edl->session->proxy_state!=PROXY_DISABLED ?
                _("Disable proxy") : _("Enable proxy"));
+// *** CONTEXT_HELP ***
+       context_help_set_keyword("Proxy");
 }
 
 void ProxyToggle::show()
@@ -2403,6 +2496,12 @@ int ProxyToggle::handle_event()
                mwindow->enable_proxy();
        mwindow->gui->lock_window("ProxyToggle::handle_event");
        set_tooltip(!disabled ? _("Disable proxy") : _("Enable proxy"));
+       ProxyDialog *dialog = mwindow->gui->mainmenu->proxy->dialog;
+       if( dialog && dialog->gui ) {
+               dialog->gui->lock_window("ProxyToggle::handle_event");
+               dialog->gui->update();
+               dialog->gui->unlock_window();
+       }
        return 1;
 }
 
@@ -2416,6 +2515,6 @@ int ProxyToggle::keypress_event()
                        return handle_event();
                }
        }
-       return 0;
+       return context_help_check_and_show();
 }