add deselect to editpopup menu, drag edit select/deselect
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / mwindowgui.C
index 2350f92e96c6a37c49f757f57875839f7de9ba8d..17078ba4eae650dc1a50c4a308b5204e37023458 100644 (file)
@@ -59,6 +59,7 @@
 #include "record.h"
 #include "recordgui.h"
 #include "renderengine.h"
+#include "remotecontrol.h"
 #include "resourcethread.h"
 #include "samplescroll.h"
 #include "shbtnprefs.h"
@@ -72,6 +73,8 @@
 #include "transitionpopup.h"
 #include "vwindowgui.h"
 #include "vwindow.h"
+#include "wintv.h"
+#include "x10tv.h"
 #include "zoombar.h"
 
 #define PANE_DRAG_MARGIN MAX(mwindow->theme->pane_w, mwindow->theme->pane_h)
@@ -100,6 +103,7 @@ MWindowGUI::MWindowGUI(MWindow *mwindow)
        drag_popup = 0;
 
        render_engine = 0;
+       render_engine_id = -1;
        for(int i = 0; i < TOTAL_PANES; i++)
                pane[i] = 0;
 
@@ -155,33 +159,56 @@ 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();
 
 
        if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
        set_icon(mwindow->theme->get_image("mwindow_icon"));
        remote_control = new RemoteControl(this);
-       cwindow_remote_handler = new CWindowRemoteHandler(remote_control);
-       record_remote_handler = new RecordRemoteHandler(remote_control);
+       cwindow_remote_handler = 0;
+       record_remote_handler = 0;
+#ifdef HAVE_X10TV
+// should be first, use if plugged
+       if( !cwindow_remote_handler && mwindow->x10tv ) {
+               cwindow_remote_handler = (RemoteHandler*)
+                       new X10TVCWindowHandler(mwindow->x10tv, remote_control);
+               record_remote_handler = (RemoteHandler*)
+                       new X10TVRecordHandler(mwindow->x10tv, remote_control);
+       }
+#endif
+#ifdef HAVE_WINTV
+       if( !cwindow_remote_handler && mwindow->wintv ) {
+               cwindow_remote_handler = (RemoteHandler*)
+                       new WinTVCWindowHandler(mwindow->wintv, remote_control);
+               record_remote_handler = (RemoteHandler*)
+                       new WinTVRecordHandler(mwindow->wintv, remote_control);
+       }
+#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 x = get_w() - MainShBtns::calculate_w(-1, 0, -1);
-       add_subwindow(mainmenu = new MainMenu(mwindow, this, x));
-       mainmenu->create_objects();
-       add_subwindow(mainshbtns = new MainShBtns(mwindow, x, -1));
+       int x1 = get_w() - MainShBtns::calculate_w(-1, 0, -1) - xS(5);
+       add_subwindow(mainshbtns = new MainShBtns(mwindow, x1, -1));
        mainshbtns->load(mwindow->preferences);
+       int x2 = x1 - mwindow->theme->stack_button_w - xS(5);
+       add_subwindow(stack_button = new StackButton(mwindow, x2, yS(2)));
+       add_subwindow(mainmenu = new MainMenu(mwindow, this, x2));
+       mainmenu->create_objects();
        mwindow->theme->get_mwindow_sizes(this, get_w(), get_h());
        mwindow->theme->draw_mwindow_bg(this);
        if(debug) printf("MWindowGUI::create_objects %d\n", __LINE__);
 
        add_subwindow(mbuttons = new MButtons(mwindow, this));
        mbuttons->create_objects();
-       int x1 = mbuttons->get_x() + mbuttons->get_w(), y1 = mbuttons->get_y()+yS(2);
-       add_subwindow(proxy_toggle = new ProxyToggle(mwindow, mbuttons, x1, y1));
-       x1 += proxy_toggle->get_w() + xS(3);
+       int y1 = mbuttons->get_y()+yS(2);
+       add_subwindow(proxy_toggle = new ProxyToggle(mwindow, mbuttons, x2, y1));
        add_subwindow(ffmpeg_toggle = new FFMpegToggle(mwindow, mbuttons, x1, y1));
 
        pane[TOP_LEFT_PANE] = new TimelinePane(mwindow,
@@ -289,15 +316,16 @@ 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 x = w - MainShBtns::calculate_w(-1, 0, -1);
-       mainmenu->resize_event(x, mainmenu->get_h());
-       mainshbtns->reposition_window(x, -1);
+       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());
+       mainmenu->resize_event(x2, mainmenu->get_h());
        mwindow->theme->get_mwindow_sizes(this, w, h);
        mwindow->theme->draw_mwindow_bg(this);
        mbuttons->resize_event();
-       int x1 = mbuttons->get_x() + mbuttons->get_w(), y1 = mbuttons->get_y()+yS(2);
-       proxy_toggle->reposition_window(x1, y1);
-       x1 += proxy_toggle->get_w() + xS(3);
+       int y1 = mbuttons->get_y()+yS(2);
+       proxy_toggle->reposition_window(x2, y1);
        ffmpeg_toggle->reposition_window(x1, y1);
        statusbar->resize_event();
        zoombar->resize_event();
@@ -609,6 +637,7 @@ void MWindowGUI::flash_canvas(int flush)
 int MWindowGUI::show_window(int flush)
 {
        int ret = BC_WindowBase::show_window(flush);
+       stack_button->update();
        update_proxy_toggle();
        return ret;
 }
@@ -1050,24 +1079,39 @@ 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);
-               result = 1;
+               if( !alt_down() && ctrl_down() ) {
+                       mwindow->edl->tracks->clear_selected_edits();
+                       draw_overlays(1);
+                       result = 1;
+               }
                break;
+       case 'a':
+               if( !ctrl_down() && alt_down() ) {
+                       stop_transport("MWindowGUI::keypress_event 1");
+                       mwindow->nearest_auto_keyframe(shift_down(),
+                               !ctrl_down() ? PLAY_FORWARD : PLAY_REVERSE);
+                       result = 1;
+               }
+               else if( ctrl_down() && alt_down() ) {
+                       mwindow->select_edits(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;
@@ -1111,17 +1155,29 @@ int MWindowGUI::keypress_event()
                result = 1;
                break;
        case 'M':
-               collapse = 1;
+               mwindow->cut_selected_edits(0, 1);
+               result = 1;
+               break;
        case BACKSPACE:
        case 'm':
-               mwindow->cut_selected_edits(0, collapse);
+               mwindow->cut_selected_edits(0, 0);
                result = 1;
                break;
        case 'z':
-               collapse = 1;
+               if( !alt_down() ) {
+                       // z and ctrl-z both are undo, z mainmenu item
+                       if( mwindow->session->current_operation == NO_OPERATION )
+                               mwindow->undo_entry(this);
+                       result = 1;
+               }
+               else if( ctrl_down() ) {
+                       mwindow->cut_selected_edits(1, 1);
+                       result = 1;
+               }
+               break;
        case 'x':
                if( !ctrl_down() || alt_down() ) break;
-               mwindow->cut_selected_edits(1, collapse);
+               mwindow->cut_selected_edits(1, 0);
                result = 1;
                break;
 
@@ -1217,18 +1273,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);
@@ -1296,6 +1352,19 @@ void MWindowGUI::use_android_remote(int on)
        if( android_control ) return;
        android_control = new AndroidControl(this);
 }
+int MWindowGUI::keyev_grab_remote()
+{
+       if( cwindow_remote_handler && cwindow_remote_handler->is_keytv() &&
+           record_remote_handler  && record_remote_handler->is_keytv() )
+               return 0;
+       delete cwindow_remote_handler;
+       delete record_remote_handler;
+       cwindow_remote_handler = (RemoteHandler*)
+               new CWindowKeyEvHandler(mwindow->gui->remote_control);
+       record_remote_handler = (RemoteHandler*)
+               new RecordKeyEvHandler(mwindow->gui->remote_control);
+       return 1;
+}
 
 int MWindowGUI::close_event()
 {
@@ -1757,6 +1826,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);
 
@@ -2231,6 +2301,19 @@ void MWindowGUI::stop_transport(const char *lock_msg)
        }
 }
 
+void MWindowGUI::close_keyvalue_popup()
+{
+       if( !keyvalue_popup ) return;
+       delete keyvalue_popup;
+       keyvalue_popup = 0;
+}
+
+void MWindowGUI::open_keyvalue_popup(BC_SubWindow *popup)
+{
+       close_keyvalue_popup();
+       keyvalue_popup = popup;
+}
+
 PaneButton::PaneButton(MWindow *mwindow, int x, int y)
  : BC_Button(x, y, mwindow->theme->get_image_set("pane"))
 {
@@ -2291,13 +2374,37 @@ int FFMpegToggle::handle_event()
        set_tooltip(ffmpeg_early_probe ? FFMPEG_EARLY_TIP : FFMPEG_LATE_TIP);
        mwindow->preferences->set_file_probe_armed("FFMPEG_Early", ffmpeg_early_probe);
        mwindow->preferences->set_file_probe_armed("FFMPEG_Late", !ffmpeg_early_probe);
-
+       mwindow->update_preferences(mwindow->preferences);
        mwindow->show_warning(&mwindow->preferences->warn_indexes,
                _("Changing the base codecs may require rebuilding indexes."));
        return 1;
 }
 
 
+StackButton::StackButton(MWindow *mwindow, int x, int y)
+ : BC_GenericButton(x, y, mwindow->theme->stack_button_w, "0")
+{
+       this->mwindow = mwindow;
+       set_tooltip(_("Close EDL"));
+}
+
+int StackButton::handle_event()
+{
+       mwindow->save_backup();
+       mwindow->stack_pop();
+       return 1;
+}
+
+void StackButton::update()
+{
+       char text[BCSTRLEN];
+       int i = mwindow->stack.size();
+       sprintf(text, "%d", i);
+       set_text(text);
+       draw_face();
+}
+
+
 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 :