add binfolder path relative filters, fix gbrp color model, vwdw timebar tweaks, title...
[goodguy/history.git] / cinelerra-5.1 / cinelerra / timebar.C
index 7d25fb2c3195e37563ad58db99cefa8df4427a2c..44e321724135526a203b68c2d3286f1165131ca6 100644 (file)
  *
  */
 
+#include "awindow.h"
+#include "awindowgui.h"
 #include "bcsignals.h"
 #include "clip.h"
 #include "cplayback.h"
 #include "cursors.h"
 #include "cwindow.h"
+#include "cwindowgui.h"
 #include "edl.h"
 #include "edlsession.h"
 #include "filexml.h"
@@ -70,6 +73,8 @@ LabelGUI::LabelGUI(MWindow *mwindow, TimeBar *timebar,
 
 LabelGUI::~LabelGUI()
 {
+       if( timebar->drag_label == this )
+               timebar->drag_label = 0;
 }
 
 int LabelGUI::get_y(MWindow *mwindow, TimeBar *timebar)
@@ -92,7 +97,7 @@ void LabelGUI::reposition(int flush)
 
 int LabelGUI::button_press_event()
 {
-       int result = 0;
+       int result = test_drag_label(1);
 
        if( this->is_event_win() && get_buttonpress() == 3 ) {
                if( label ) {
@@ -109,12 +114,58 @@ int LabelGUI::button_press_event()
        return result;
 }
 
+int LabelGUI::button_release_event()
+{
+       int ret = BC_Toggle::button_release_event();
+       test_drag_label(0);
+       return ret;
+}
+
+int LabelGUI::test_drag_label(int press)
+{
+       if( is_event_win() && get_buttonpress() == 1 ) {
+               switch( timebar->current_operation ) {
+               case TIMEBAR_NONE:
+                       if( press && get_value() ) {
+                               timebar->current_operation = TIMEBAR_DRAG_LABEL;
+                               timebar->drag_label = this;
+                               set_cursor(HSEPARATE_CURSOR, 0, 0);
+                               mwindow->undo->update_undo_before(_("drag label"), this);
+                               return 1;
+                       }
+                       break;
+               case TIMEBAR_DRAG_LABEL:
+                       if( !press ) {
+                               timebar->current_operation = TIMEBAR_NONE;
+                               timebar->drag_label = 0;
+                               set_cursor(ARROW_CURSOR, 0, 0);
+                               mwindow->undo->update_undo_after(_("drag label"), LOAD_TIMEBAR);
+                               mwindow->awindow->gui->async_update_assets(); // labels folder
+                       }
+                       break;
+               }
+       }
+       return 0;
+}
+
 int LabelGUI::handle_event()
 {
        timebar->select_label(position);
        return 1;
 }
 
+void LabelGUI::update_value()
+{
+       EDL *edl = timebar->get_edl();
+       double start = edl->local_session->get_selectionstart(1);
+       double end = edl->local_session->get_selectionend(1);
+       int v = ( label->position >= start && end >= label->position ) ||
+           edl->equivalent(label->position, start) ||
+           edl->equivalent(label->position, end) ||
+           timebar->drag_label == this ? 1 : 0;
+       update(v);
+}
+
 
 InPointGUI::InPointGUI(MWindow *mwindow, TimeBar *timebar,
        int64_t pixel, double position)
@@ -170,6 +221,7 @@ TimeBar::TimeBar(MWindow *mwindow, BC_WindowBase *gui,
 //printf("TimeBar::TimeBar %d %d %d %d\n", x, y, w, h);
        this->gui = gui;
        this->mwindow = mwindow;
+       this->drag_label = 0;
        label_edit = new LabelEdit(mwindow, mwindow->awindow, 0);
        pane = 0;
        highlighted = 0;
@@ -205,12 +257,12 @@ int64_t TimeBar::position_to_pixel(double position)
 double TimeBar::pixel_to_position(int pixel)
 {
        if( pane ) {
-               pixel += mwindow->edl->local_session->view_start[pane->number];
+               pixel += get_edl()->local_session->view_start[pane->number];
        }
 
        return (double)pixel *
-               mwindow->edl->local_session->zoom_sample /
-               mwindow->edl->session->sample_rate;
+               get_edl()->local_session->zoom_sample /
+               get_edl()->session->sample_rate;
 }
 
 void TimeBar::update_labels()
@@ -244,23 +296,16 @@ void TimeBar::update_labels()
                                                gui->pixel = pixel;
                                                gui->reposition(0);
                                        }
-                                       else {
-                                               gui->draw_face(1,0);
-                                       }
+//                                     else {
+//                                             gui->draw_face(1,0);
+//                                     }
 
                                        labels.values[output]->position = current->position;
                                        labels.values[output]->set_tooltip(current->textstr);
                                        labels.values[output]->label = current;
                                }
 
-                               if( edl->local_session->get_selectionstart(1) <= current->position &&
-                                   edl->local_session->get_selectionend(1) >= current->position )
-                                       labels.values[output]->update(1);
-                               else
-                               if( labels.values[output]->get_value() )
-                                       labels.values[output]->update(0);
-
-                               output++;
+                               labels.values[output++]->update_value();
                        }
                }
        }
@@ -277,35 +322,52 @@ void TimeBar::update_labels()
 
 void TimeBar::update_highlights()
 {
+       EDL *edl = get_edl();
+       if( !edl ) return;
        for( int i = 0; i < labels.total; i++ ) {
-               LabelGUI *label = labels.values[i];
-               if( mwindow->edl->equivalent(label->position,
-                               mwindow->edl->local_session->get_selectionstart(1)) ||
-                   mwindow->edl->equivalent(label->position,
-                               mwindow->edl->local_session->get_selectionend(1)) ) {
-                       if( !label->get_value() ) label->update(1);
-               }
-               else
-                       if( label->get_value() ) label->update(0);
+               labels.values[i]->update_value();
        }
 
-       if( mwindow->edl->equivalent(mwindow->edl->local_session->get_inpoint(),
-                       mwindow->edl->local_session->get_selectionstart(1)) ||
-               mwindow->edl->equivalent(mwindow->edl->local_session->get_inpoint(),
-                       mwindow->edl->local_session->get_selectionend(1)) ) {
+       if( edl->equivalent(edl->local_session->get_inpoint(),
+                       edl->local_session->get_selectionstart(1)) ||
+               edl->equivalent(edl->local_session->get_inpoint(),
+                       edl->local_session->get_selectionend(1)) ) {
                if( in_point ) in_point->update(1);
        }
        else
                if( in_point ) in_point->update(0);
 
-       if( mwindow->edl->equivalent(mwindow->edl->local_session->get_outpoint(),
-                       mwindow->edl->local_session->get_selectionstart(1)) ||
-               mwindow->edl->equivalent(mwindow->edl->local_session->get_outpoint(),
-                       mwindow->edl->local_session->get_selectionend(1)) ) {
+       if( edl->equivalent(edl->local_session->get_outpoint(),
+                       edl->local_session->get_selectionstart(1)) ||
+               edl->equivalent(edl->local_session->get_outpoint(),
+                       edl->local_session->get_selectionend(1)) ) {
                if( out_point ) out_point->update(1);
        }
        else
                if( out_point ) out_point->update(0);
+
+       draw_inout_highlight();
+}
+
+void TimeBar::draw_inout_highlight()
+{
+       EDL *edl = get_edl();
+       if( !edl->local_session->inpoint_valid() ) return;
+       if( !edl->local_session->outpoint_valid() ) return;
+       double in_position = edl->local_session->get_inpoint();
+       double out_position = edl->local_session->get_outpoint();
+       if( in_position >= out_position ) return;
+       int in_x = position_to_pixel(in_position);
+       int out_x = position_to_pixel(out_position);
+       CLAMP(in_x, 0, get_w());
+       CLAMP(out_x, 0, get_w());
+       set_color(mwindow->theme->inout_highlight_color);
+       int lw = 5;
+       set_line_width(lw);
+       set_inverse();
+       draw_line(in_x, get_h()-2*lw, out_x, get_h()-2*lw);
+       set_opaque();
+       set_line_width(1);
 }
 
 void TimeBar::update_points()
@@ -393,7 +455,7 @@ void TimeBar::update(int flush)
 //printf("TimeBar::update %d %d\n", __LINE__, x);
                double position = pixel_to_position(x);
 
-               position = get_edl()->align_to_frame(position, 0);
+               position = mwindow->edl->align_to_frame(position, 0);
                pixel = position_to_pixel(position);
                update_clock(position);
        }
@@ -527,32 +589,19 @@ double TimeBar::get_edl_length()
 
 int TimeBar::get_preview_pixels(int &x1, int &x2)
 {
-       x1 = 0;
-       x2 = 0;
-
+       x1 = 0;  x2 = get_w();
        get_edl_length();
-
-       if( get_edl() ) {
-               if( !EQUIV(edl_length, 0) ) {
-                       if( get_edl()->local_session->preview_end <= 0 ||
-                           get_edl()->local_session->preview_end > edl_length )
-                               get_edl()->local_session->preview_end = edl_length;
-                       if( get_edl()->local_session->preview_start >
-                               get_edl()->local_session->preview_end )
-                               get_edl()->local_session->preview_start = 0;
-                       x1 = (int)(get_edl()->local_session->preview_start / time_per_pixel);
-                       x2 = (int)(get_edl()->local_session->preview_end / time_per_pixel);
-               }
-               else {
-                       x1 = 0;
-                       x2 = get_w();
+       EDL *edl = get_edl();
+       if( edl && !EQUIV(edl_length, 0) ) {
+               double preview_start = edl->local_session->preview_start;
+               double preview_end = edl->local_session->preview_end;
+               if( preview_end < 0 || preview_end > edl_length )
+                       preview_end = edl_length;
+               if( preview_end >= preview_start ) {
+                       x1 = (int)(preview_start / time_per_pixel);
+                       x2 = (int)(preview_end / time_per_pixel);
                }
        }
-// printf("TimeBar::get_preview_pixels %f %f %d %d\n",
-//     get_edl()->local_session->preview_start,
-//     get_edl()->local_session->preview_end,
-//     x1,
-//     x2);
        return 0;
 }
 
@@ -586,6 +635,8 @@ int TimeBar::test_preview(int buttonpress)
                        if( buttonpress ) {
                                current_operation = TIMEBAR_DRAG_RIGHT;
                                start_position = get_edl()->local_session->preview_end;
+                               if( start_position < 0 || start_position > edl_length )
+                                       start_position = edl_length;
                                start_cursor_x = x;
                        }
                        else if( get_cursor() != RIGHT_CURSOR )
@@ -599,6 +650,8 @@ int TimeBar::test_preview(int buttonpress)
                                current_operation = TIMEBAR_DRAG_CENTER;
                                starting_start_position = get_edl()->local_session->preview_start;
                                starting_end_position = get_edl()->local_session->preview_end;
+                               if( starting_end_position < 0 || starting_end_position > edl_length )
+                                       starting_end_position = edl_length;
                                start_cursor_x = x;
                        }
                        if( get_cursor() != HSEPARATE_CURSOR )
@@ -617,26 +670,30 @@ int TimeBar::test_preview(int buttonpress)
 int TimeBar::move_preview(int &redraw)
 {
        int result = 0, x = get_relative_cursor_x();
-
-       if( current_operation == TIMEBAR_DRAG_LEFT ) {
+       switch( current_operation ) {
+       case TIMEBAR_DRAG_LEFT: {
                get_edl()->local_session->preview_start =
                        start_position + time_per_pixel * (x - start_cursor_x);
-               CLAMP(get_edl()->local_session->preview_start,
-                       0,
-                       get_edl()->local_session->preview_end);
+               double preview_end = get_edl()->local_session->preview_end;
+               if( preview_end < 0 || preview_end > edl_length )
+                       preview_end = get_edl()->local_session->preview_end = edl_length;
+               CLAMP(get_edl()->local_session->preview_start, 0, preview_end);
                result = 1;
-       }
-       else
-       if( current_operation == TIMEBAR_DRAG_RIGHT ) {
-               get_edl()->local_session->preview_end =
+               break; }
+       case TIMEBAR_DRAG_RIGHT: {
+               double preview_end = get_edl()->local_session->preview_end =
                        start_position + time_per_pixel * (x - start_cursor_x);
-               CLAMP(get_edl()->local_session->preview_end,
-                       get_edl()->local_session->preview_start,
-                       edl_length);
+               double preview_start = get_edl()->local_session->preview_start;
+               if( preview_end >= edl_length && !preview_start ) {
+                       get_edl()->local_session->preview_end = -1;
+                       if( preview_start > preview_end )
+                               preview_start = get_edl()->local_session->preview_start = preview_end;
+               }
+               else
+                       CLAMP(get_edl()->local_session->preview_end, preview_start, edl_length);
                result = 1;
-       }
-       else
-       if( current_operation == TIMEBAR_DRAG_CENTER ) {
+               break; }
+       case TIMEBAR_DRAG_CENTER: {
                double dt = time_per_pixel * (x - start_cursor_x);
                get_edl()->local_session->preview_start = starting_start_position + dt;
                get_edl()->local_session->preview_end = starting_end_position + dt;
@@ -650,6 +707,7 @@ int TimeBar::move_preview(int &redraw)
                        get_edl()->local_session->preview_end = edl_length;
                }
                result = 1;
+               break; }
        }
 
 //printf("TimeBar::move_preview %d %d\n", __LINE__, current_operation);
@@ -684,7 +742,7 @@ int TimeBar::button_press_event()
                        result = test_preview(1);
                }
 // Change time format
-               else if( ctrl_down() ) {
+               else if( !is_vwindow() && ctrl_down() ) {
                        if( get_buttonpress() == 1 )
                                mwindow->next_time_format();
                        else
@@ -696,7 +754,7 @@ int TimeBar::button_press_event()
                        stop_playback();
 
 // Select region between two labels
-                       if( get_double_click() ) {
+                       if( !is_vwindow() && get_double_click() ) {
                                int x = get_relative_cursor_x();
                                double position = pixel_to_position(x);
 // Test labels
@@ -725,45 +783,61 @@ int TimeBar::cursor_motion_event()
        int result = 0;
        int redraw = 0;
 
-//printf("TimeBar::cursor_motion_event %d %p %d\n", __LINE__, this, current_operation);
-       switch( current_operation )
-       {
-               case TIMEBAR_DRAG:
-               {
-                       update_cursor();
-                       handle_mwindow_drag();
-                       result = 1;
-//printf("TimeBar::cursor_motion_event %d %d\n", __LINE__, current_operation);
-                       break;
-               }
-
-
-               case TIMEBAR_DRAG_LEFT:
-               case TIMEBAR_DRAG_RIGHT:
-               case TIMEBAR_DRAG_CENTER:
-                       if( has_preview() )
-                               result = move_preview(redraw);
-                       break;
-
-               default:
-                       if( cursor_above() ) {
-                               highlighted = 1;
-                               redraw = 1;
+       switch( current_operation ) {
+       case TIMEBAR_DRAG_LEFT:
+       case TIMEBAR_DRAG_RIGHT:
+       case TIMEBAR_DRAG_CENTER:
+               if( has_preview() )
+                       result = move_preview(redraw);
+               break;
+
+       case TIMEBAR_DRAG_LABEL:
+               if( drag_label ) {
+                       EDL *edl = get_edl();
+                       int pixel = get_relative_cursor_x();
+                       double position = pixel_to_position(pixel);
+                       if( drag_label->label )
+                               drag_label->label->position = position;
+                       else if( drag_label == in_point ) {
+                               if( out_point && edl->local_session->outpoint_valid() ) {
+                                       double out_pos = edl->local_session->get_outpoint();
+                                       if( position > out_pos ) {
+                                               edl->local_session->set_outpoint(position);
+                                               drag_label = out_point;
+                                               position = out_pos;
+                                       }
+                               }
+                               edl->local_session->set_inpoint(position);
+                       }
+                       else if( drag_label == out_point ) {
+                               if( in_point && edl->local_session->inpoint_valid() ) {
+                                       double in_pos = edl->local_session->get_inpoint();
+                                       if( position < in_pos ) {
+                                               edl->local_session->set_inpoint(position);
+                                               drag_label = in_point;
+                                               position = in_pos;
+                                       }
+                               }
+                               edl->local_session->set_outpoint(position);
                        }
+               }
+       // fall thru
+       case TIMEBAR_DRAG:
+               update_cursor();
+               handle_mwindow_drag();
+               result = 1;
+               break;
 
-//printf("TimeBar::cursor_motion_event 20\n");
-                       if( has_preview() )
-                               result = test_preview(0);
-//printf("TimeBar::cursor_motion_event 30\n");
-                       break;
+       default:
+               if( has_preview() )
+                       result = test_preview(0);
+               break;
        }
 
 
-//printf("TimeBar::cursor_motion_event %d %d\n", __LINE__, current_operation);
        if( redraw ) {
                update(1);
        }
-//printf("TimeBar::cursor_motion_event %d %p %d\n", __LINE__, this, current_operation);
 
        return result;
 }
@@ -819,14 +893,14 @@ void TimeBar::handle_mwindow_drag()
 int TimeBar::select_region(double position)
 {
        Label *start = 0, *end = 0, *current;
-       for( current = mwindow->edl->labels->first; current; current = NEXT ) {
+       for( current = get_edl()->labels->first; current; current = NEXT ) {
                if( current->position > position ) {
                        end = current;
                        break;
                }
        }
 
-       for( current = mwindow->edl->labels->last ; current; current = PREVIOUS ) {
+       for( current = get_edl()->labels->last ; current; current = PREVIOUS ) {
                if( current->position <= position ) {
                        start = current;
                        break;
@@ -836,28 +910,32 @@ int TimeBar::select_region(double position)
 // Select region
        if( end != start ) {
                if( !start )
-                       mwindow->edl->local_session->set_selectionstart(0);
+                       get_edl()->local_session->set_selectionstart(0);
                else
-                       mwindow->edl->local_session->set_selectionstart(start->position);
+                       get_edl()->local_session->set_selectionstart(start->position);
 
                if( !end )
-                       mwindow->edl->local_session->set_selectionend(mwindow->edl->tracks->total_length());
+                       get_edl()->local_session->set_selectionend(get_edl()->tracks->total_length());
                else
-                       mwindow->edl->local_session->set_selectionend(end->position);
+                       get_edl()->local_session->set_selectionend(end->position);
        }
        else
        if( end || start ) {
-               mwindow->edl->local_session->set_selectionstart(start->position);
-               mwindow->edl->local_session->set_selectionend(start->position);
+               get_edl()->local_session->set_selectionstart(start->position);
+               get_edl()->local_session->set_selectionend(start->position);
        }
 
 // Que the CWindow
+       mwindow->cwindow->gui->lock_window("TimeBar::select_region");
        mwindow->cwindow->update(1, 0, 0);
+       mwindow->cwindow->gui->unlock_window();
+       mwindow->gui->lock_window("TimeBar::select_region");
        mwindow->gui->hide_cursor(0);
        mwindow->gui->draw_cursor(1);
        mwindow->gui->flash_canvas(0);
        mwindow->gui->activate_timeline();
        mwindow->gui->zoombar->update();
+       mwindow->gui->unlock_window();
        update_highlights();
        return 0;
 }