change label drag cursor
[goodguy/history.git] / cinelerra-5.1 / cinelerra / timebar.C
index b295c32390ddbc8996cc3563138093f2853833a5..3f0780b732d86180fd2a036b7cb335feda6f986f 100644 (file)
@@ -24,6 +24,7 @@
 #include "cplayback.h"
 #include "cursors.h"
 #include "cwindow.h"
+#include "cwindowgui.h"
 #include "edl.h"
 #include "edlsession.h"
 #include "filexml.h"
 #include "zoombar.h"
 
 
-LabelGUI::LabelGUI(MWindow *mwindow,
-       TimeBar *timebar,
-       int64_t pixel,
-       int y,
-       double position,
-       VFrame **data)
- : BC_Toggle(translate_pixel(mwindow, pixel),
-               y,
-               data ? data : mwindow->theme->label_toggle,
-               0)
+LabelGUI::LabelGUI(MWindow *mwindow, TimeBar *timebar,
+       int64_t pixel, int y,
+       double position, VFrame **data)
+ : BC_Toggle(translate_pixel(mwindow, pixel), y,
+               data ? data : mwindow->theme->label_toggle, 0)
 {
        this->mwindow = mwindow;
        this->timebar = timebar;
@@ -75,6 +71,8 @@ LabelGUI::LabelGUI(MWindow *mwindow,
 
 LabelGUI::~LabelGUI()
 {
+       if( timebar->drag_label == this )
+               timebar->drag_label = 0;
 }
 
 int LabelGUI::get_y(MWindow *mwindow, TimeBar *timebar)
@@ -97,20 +95,55 @@ 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)
-                       timebar->label_edit->start(label);
+       if( this->is_event_win() && get_buttonpress() == 3 ) {
+               if( label ) {
+                       int cur_x, cur_y;
+                       get_abs_cursor(cur_x, cur_y, 0);
+                       timebar->label_edit->start(label, cur_x, cur_y);
+               }
                result = 1;
        } else {
                result = BC_Toggle::button_press_event();
        }
-       if (label)
+       if( label )
                set_tooltip(this->label->textstr);
        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;
+                               set_cursor(ARROW_CURSOR, 0, 0);
+                               mwindow->undo->update_undo_after(_("drag label"), LOAD_TIMEBAR);
+                       }
+                       break;
+               }
+       }
+       return 0;
+}
+
 int LabelGUI::handle_event()
 {
        timebar->select_label(position);
@@ -118,16 +151,11 @@ int LabelGUI::handle_event()
 }
 
 
-InPointGUI::InPointGUI(MWindow *mwindow,
-       TimeBar *timebar,
-       int64_t pixel,
-       double position)
- : LabelGUI(mwindow,
-       timebar,
-       pixel,
-       get_y(mwindow, timebar),
-       position,
-       mwindow->theme->in_point)
+InPointGUI::InPointGUI(MWindow *mwindow, TimeBar *timebar,
+       int64_t pixel, double position)
+ : LabelGUI(mwindow, timebar,
+       pixel, get_y(mwindow, timebar),
+       position, mwindow->theme->in_point)
 {
 //printf("InPointGUI::InPointGUI %d %d\n", pixel, get_y(mwindow, timebar));
 }
@@ -143,16 +171,11 @@ int InPointGUI::get_y(MWindow *mwindow, TimeBar *timebar)
 }
 
 
-OutPointGUI::OutPointGUI(MWindow *mwindow,
-       TimeBar *timebar,
-       int64_t pixel,
-       double position)
- : LabelGUI(mwindow,
-       timebar,
-       pixel,
-       get_y(mwindow, timebar),
-       position,
-       mwindow->theme->out_point)
+OutPointGUI::OutPointGUI(MWindow *mwindow, TimeBar *timebar,
+       int64_t pixel, double position)
+ : LabelGUI(mwindow, timebar,
+       pixel, get_y(mwindow, timebar),
+       position, mwindow->theme->out_point)
 {
 //printf("OutPointGUI::OutPointGUI %d %d\n", pixel, get_y(mwindow, timebar));
 }
@@ -166,10 +189,8 @@ int OutPointGUI::get_y(MWindow *mwindow, TimeBar *timebar)
 }
 
 
-PresentationGUI::PresentationGUI(MWindow *mwindow,
-       TimeBar *timebar,
-       int64_t pixel,
-       double position)
+PresentationGUI::PresentationGUI(MWindow *mwindow, TimeBar *timebar,
+       int64_t pixel, double position)
  : LabelGUI(mwindow, timebar, pixel, get_y(mwindow, timebar), position)
 {
 }
@@ -177,17 +198,14 @@ PresentationGUI::~PresentationGUI()
 {
 }
 
-TimeBar::TimeBar(MWindow *mwindow,
-       BC_WindowBase *gui,
-       int x,
-       int y,
-       int w,
-       int h)
+TimeBar::TimeBar(MWindow *mwindow, BC_WindowBase *gui,
+       int x, int y, int w, int h)
  : BC_SubWindow(x, y, w, h)
 {
 //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;
@@ -195,9 +213,9 @@ TimeBar::TimeBar(MWindow *mwindow,
 
 TimeBar::~TimeBar()
 {
-       if(in_point) delete in_point;
-       if(out_point) delete out_point;
-       if(label_edit) delete label_edit;
+       delete in_point;
+       delete out_point;
+       delete label_edit;
        labels.remove_all_objects();
        presentations.remove_all_objects();
 }
@@ -222,14 +240,13 @@ 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];
+       if( pane ) {
+               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()
@@ -237,19 +254,12 @@ void TimeBar::update_labels()
        int output = 0;
        EDL *edl = get_edl();
 
-       if(edl)
-       {
-               for(Label *current = edl->labels->first;
-                       current;
-                       current = NEXT)
-               {
+       if( edl ) {
+               for( Label *current=edl->labels->first; current; current=NEXT ) {
                        int64_t pixel = position_to_pixel(current->position);
-
-                       if(pixel >= 0 && pixel < get_w())
-                       {
+                       if( pixel >= 0 && pixel < get_w()  ) {
 // Create new label
-                               if(output >= labels.total)
-                               {
+                               if( output >= labels.total ) {
                                        LabelGUI *new_label;
                                        add_subwindow(new_label =
                                                new LabelGUI(mwindow,
@@ -266,13 +276,11 @@ void TimeBar::update_labels()
 // Reposition old label
                                {
                                        LabelGUI *gui = labels.values[output];
-                                       if(gui->pixel != pixel)
-                                       {
+                                       if( gui->pixel != pixel ) {
                                                gui->pixel = pixel;
                                                gui->reposition(0);
                                        }
-                                       else
-                                       {
+                                       else {
                                                gui->draw_face(1,0);
                                        }
 
@@ -281,11 +289,11 @@ void TimeBar::update_labels()
                                        labels.values[output]->label = current;
                                }
 
-                               if(edl->local_session->get_selectionstart(1) <= current->position &&
-                                       edl->local_session->get_selectionend(1) >= current->position)
+                               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())
+                               if( labels.values[output]->get_value() )
                                        labels.values[output]->update(0);
 
                                output++;
@@ -305,39 +313,60 @@ void TimeBar::update_labels()
 
 void TimeBar::update_highlights()
 {
-       for(int i = 0; i < labels.total; i++)
-       {
+       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);
+               if( edl->equivalent(label->position,
+                               edl->local_session->get_selectionstart(1)) ||
+                   edl->equivalent(label->position,
+                               edl->local_session->get_selectionend(1)) ) {
+                       if( !label->get_value() ) label->update(1);
                }
                else
-                       if(label->get_value()) label->update(0);
+                       if( label->get_value() ) label->update(0);
        }
 
-       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(in_point) in_point->update(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( 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(out_point) out_point->update(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);
+               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()
@@ -346,34 +375,27 @@ void TimeBar::update_points()
        int64_t pixel = !edl ? 0 :
                position_to_pixel(edl->local_session->get_inpoint());
 
-       if(in_point)
-       {
-               if(edl &&
-                       edl->local_session->inpoint_valid() &&
-                       pixel >= 0 && pixel < get_w())
-               {
-                       if(!EQUIV(edl->local_session->get_inpoint(), in_point->position) ||
-                               in_point->pixel != pixel)
-                       {
+       if( in_point ) {
+               if( edl && edl->local_session->inpoint_valid() &&
+                   pixel >= 0 && pixel < get_w() ) {
+                       if( !EQUIV(edl->local_session->get_inpoint(), in_point->position) ||
+                           in_point->pixel != pixel ) {
                                in_point->pixel = pixel;
                                in_point->position = edl->local_session->get_inpoint();
                                in_point->reposition(0);
                        }
-                       else
-                       {
+                       else {
                                in_point->draw_face(1, 0);
                        }
                }
-               else
-               {
+               else {
                        delete in_point;
                        in_point = 0;
                }
        }
        else
-       if(edl && edl->local_session->inpoint_valid() &&
-               pixel >= 0 && pixel < get_w())
-       {
+       if( edl && edl->local_session->inpoint_valid() &&
+           pixel >= 0 && pixel < get_w() ) {
                add_subwindow(in_point = new InPointGUI(mwindow,
                        this, pixel, edl->local_session->get_inpoint()));
                in_point->set_cursor(ARROW_CURSOR, 0, 0);
@@ -382,34 +404,27 @@ void TimeBar::update_points()
        pixel = !edl ? 0 :
                 position_to_pixel(edl->local_session->get_outpoint());
 
-       if(out_point)
-       {
+       if( out_point ) {
                if( edl && edl->local_session->outpoint_valid() &&
-                       pixel >= 0 && pixel < get_w())
-               {
-                       if(!EQUIV(edl->local_session->get_outpoint(), out_point->position) ||
-                               out_point->pixel != pixel)
-                       {
+                   pixel >= 0 && pixel < get_w()) {
+                       if( !EQUIV(edl->local_session->get_outpoint(), out_point->position) ||
+                           out_point->pixel != pixel ) {
                                out_point->pixel = pixel;
                                out_point->position = edl->local_session->get_outpoint();
                                out_point->reposition(0);
                        }
-                       else
-                       {
+                       else {
                                out_point->draw_face(1, 0);
                        }
                }
-               else
-               {
+               else {
                        delete out_point;
                        out_point = 0;
                }
        }
        else
-       if(edl &&
-               edl->local_session->outpoint_valid() &&
-               pixel >= 0 && pixel < get_w())
-       {
+       if( edl && edl->local_session->outpoint_valid() &&
+           pixel >= 0 && pixel < get_w() ) {
                add_subwindow(out_point = new OutPointGUI(mwindow,
                        this, pixel, edl->local_session->get_outpoint()));
                out_point->set_cursor(ARROW_CURSOR, 0, 0);
@@ -434,27 +449,23 @@ void TimeBar::update(int flush)
        int64_t pixel = -1;
        int x = get_relative_cursor_x();
 // Draw highlight position
-       if(edl &&
-               (highlighted || current_operation == TIMEBAR_DRAG) &&
-               x >= 0 && x < get_w())
-       {
+       if( edl && (highlighted || current_operation == TIMEBAR_DRAG) &&
+           x >= 0 && x < get_w() ) {
 //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);
        }
 
-       if(pixel < 0)
-       {
+       if( pixel < 0 ) {
                double position = test_highlight();
-               if(position >= 0) pixel = position_to_pixel(position);
+               if( position >= 0 ) pixel = position_to_pixel(position);
        }
 
 
-       if(pixel >= 0 && pixel < get_w())
-       {
+       if( pixel >= 0 && pixel < get_w() ) {
                set_color(mwindow->theme->timebar_cursor_color);
                set_line_dashes(1);
 //printf("TimeBar::update %d pane=%d pixel=%jd\n", __LINE__, pane->number, pixel);
@@ -463,8 +474,7 @@ void TimeBar::update(int flush)
        }
 
 
-       if(edl)
-       {
+       if( edl ) {
                double playback_start = edl->local_session->playback_start;
                if( playback_start >= 0 ) {
                        int64_t pixel = position_to_pixel(playback_start);
@@ -481,7 +491,10 @@ void TimeBar::update(int flush)
                double position = edl->local_session->get_selectionstart(1);
                int64_t pixel = position_to_pixel(position);
 // Draw insertion point position.
-               set_color(mwindow->theme->timebar_cursor_color);
+               int color = mwindow->theme->timebar_cursor_color;
+               if( mwindow->preferences->forward_render_displacement )
+                       color ^= 0x00ffff;
+               set_color(color);
                draw_line(pixel, 0, pixel, get_h());
        }
 
@@ -526,8 +539,7 @@ void TimeBar::draw_range()
 
 
 //printf("TimeBar::draw_range %d %p\n", __LINE__, get_edl());
-       if(has_preview() && get_edl())
-       {
+       if( has_preview() && get_edl() ) {
                int x1, x2;
                get_preview_pixels(x1, x2);
 
@@ -542,8 +554,7 @@ void TimeBar::draw_range()
 
 
                EDL *edl = get_edl();
-               if(edl)
-               {
+               if( edl ) {
                        int64_t pixel = position_to_pixel(
                                edl->local_session->get_selectionstart(1));
 // Draw insertion point position if this timebar belongs to a window which
@@ -569,61 +580,27 @@ int TimeBar::draw()
 
 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 2\n");
-       if(!EQUIV(edl_length, 0))
-       {
-//printf("TimeBar::get_edl_length 3\n");
-               time_per_pixel = edl_length / get_w();
-//printf("TimeBar::get_edl_length 4\n");
-       }
-       else
-       {
-               time_per_pixel = 0;
-       }
-//printf("TimeBar::get_edl_length 5\n");
-
+       edl_length = get_edl() ? get_edl()->tracks->total_length() : 0;
+       int w1 = get_w()-1;
+       time_per_pixel = !EQUIV(edl_length, 0) ? edl_length/w1 : w1;
        return 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;
 }
 
@@ -633,59 +610,56 @@ int TimeBar::test_preview(int buttonpress)
        int result = 0;
 
 
-       if(get_edl() && cursor_inside() && buttonpress >= 0)
-       {
+       if( get_edl() && cursor_inside() && buttonpress >= 0 ) {
                int x1, x2, x = get_relative_cursor_x();
                get_preview_pixels(x1, x2);
 //printf("TimeBar::test_preview %d %d %d\n", x1, x2, x);
 // Inside left handle
-               if(x >= x1 - HANDLE_W && x < x1 + HANDLE_W &&
+               if( x >= x1 - HANDLE_W && x < x1 + HANDLE_W &&
 // Ignore left handle if both handles are up against the left side
-                       x2 > HANDLE_W)
-               {
-                       if(buttonpress)
-                       {
+                   x2 > HANDLE_W ) {
+                       if( buttonpress ) {
                                current_operation = TIMEBAR_DRAG_LEFT;
                                start_position = get_edl()->local_session->preview_start;
                                start_cursor_x = x;
                        }
-                       else if(get_cursor() != LEFT_CURSOR)
+                       else if( get_cursor() != LEFT_CURSOR )
                                set_cursor(LEFT_CURSOR, 0, 1);
                        result = 1;
                }
 // Inside right handle
-               else if(x >= x2 - HANDLE_W && x < x2 + HANDLE_W &&
+               else if( x >= x2 - HANDLE_W && x < x2 + HANDLE_W &&
 // Ignore right handle if both handles are up against the right side
-                       x1 < get_w() - HANDLE_W)
-               {
-                       if(buttonpress)
-                       {
+                   x1 < get_w() - HANDLE_W ) {
+                       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)
+                       else if( get_cursor() != RIGHT_CURSOR )
                                set_cursor(RIGHT_CURSOR, 0, 1);
                        result = 1;
                }
 // Inside preview
-               else if(get_button_down() && get_buttonpress() == 3 &&
-                       x >= x1 && x < x2)
-               {
-                       if(buttonpress)
-                       {
+               else if( get_button_down() && get_buttonpress() == 3 &&
+                   x >= x1 && x < x2 ) {
+                       if( 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)
+                       if( get_cursor() != HSEPARATE_CURSOR )
                                set_cursor(HSEPARATE_CURSOR, 0, 1);
                        result = 1;
                }
        }
 
-       if(!result && get_cursor() != ARROW_CURSOR)
+       if( !result && get_cursor() != ARROW_CURSOR )
                set_cursor(ARROW_CURSOR, 0, 1);
 
 
@@ -695,50 +669,49 @@ 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;
-               if(get_edl()->local_session->preview_start < 0)
-               {
+               if( get_edl()->local_session->preview_start < 0 ) {
                        get_edl()->local_session->preview_end -= get_edl()->local_session->preview_start;
                        get_edl()->local_session->preview_start = 0;
                }
                else
-               if(get_edl()->local_session->preview_end > edl_length)
-               {
+               if( get_edl()->local_session->preview_end > edl_length ) {
                        get_edl()->local_session->preview_start -= get_edl()->local_session->preview_end - edl_length;
                        get_edl()->local_session->preview_end = edl_length;
                }
                result = 1;
+               break; }
        }
 
 //printf("TimeBar::move_preview %d %d\n", __LINE__, current_operation);
 
-       if(result)
-       {
+       if( result ) {
                update_preview();
                redraw = 1;
        }
@@ -763,36 +736,30 @@ void TimeBar::stop_playback()
 int TimeBar::button_press_event()
 {
        int result = 0;
-       if(is_event_win() && cursor_above())
-       {
-               if(has_preview() && get_buttonpress() == 3)
-               {
+       if( is_event_win() && cursor_above() ) {
+               if( has_preview() && get_buttonpress() == 3 ) {
                        result = test_preview(1);
                }
 // Change time format
-               else if(ctrl_down())
-               {
-                       if(get_buttonpress() == 1)
+               else if( ctrl_down() ) {
+                       if( get_buttonpress() == 1 )
                                mwindow->next_time_format();
                        else
-                       if(get_buttonpress() == 2)
+                       if( get_buttonpress() == 2 )
                                mwindow->prev_time_format();
                        result = 1;
                }
-               else if(get_buttonpress() == 1)
-               {
+               else if( get_buttonpress() == 1 ) {
                        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
                                select_region(position);
                        }
-                       else
-                       {
+                       else {
 
 // Reposition highlight cursor
                                update_cursor();
@@ -816,34 +783,48 @@ int TimeBar::cursor_motion_event()
        int redraw = 0;
 
 //printf("TimeBar::cursor_motion_event %d %p %d\n", __LINE__, this, current_operation);
-       switch(current_operation)
+       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 ) {
+                               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 ) {
+                                       EDL *edl = get_edl();
+                                       edl->local_session->set_inpoint(position);
+                               }
+                               else if( drag_label == out_point ) {
+                                       EDL *edl = get_edl();
+                                       edl->local_session->set_outpoint(position);
+                               }
+                       }
+                       highlighted = 1;
+                       redraw = 1; // fall thru
+
                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())
-                       {
+                       if( cursor_above() ) {
                                highlighted = 1;
                                redraw = 1;
                        }
 
 //printf("TimeBar::cursor_motion_event 20\n");
-                       if(has_preview())
+                       if( has_preview() )
                                result = test_preview(0);
 //printf("TimeBar::cursor_motion_event 30\n");
                        break;
@@ -851,8 +832,7 @@ int TimeBar::cursor_motion_event()
 
 
 //printf("TimeBar::cursor_motion_event %d %d\n", __LINE__, current_operation);
-       if(redraw)
-       {
+       if( redraw ) {
                update(1);
        }
 //printf("TimeBar::cursor_motion_event %d %p %d\n", __LINE__, this, current_operation);
@@ -862,8 +842,7 @@ int TimeBar::cursor_motion_event()
 
 int TimeBar::cursor_leave_event()
 {
-       if(highlighted)
-       {
+       if( highlighted ) {
                highlighted = 0;
                update(1);
        }
@@ -875,7 +854,7 @@ int TimeBar::button_release_event()
 //printf("TimeBar::button_release_event %d %d\n", __LINE__, current_operation);
        int result = 0;
        int need_redraw = 0;
-       switch(current_operation)
+       switch( current_operation )
        {
                case TIMEBAR_DRAG:
                        mwindow->gui->get_focused_pane()->canvas->stop_dragscroll();
@@ -885,16 +864,14 @@ int TimeBar::button_release_event()
                        break;
 
                default:
-                       if(current_operation != TIMEBAR_NONE)
-                       {
+                       if( current_operation != TIMEBAR_NONE ) {
                                current_operation = TIMEBAR_NONE;
                                result = 1;
                        }
                        break;
        }
 
-       if((!cursor_above() && highlighted) || need_redraw)
-       {
+       if( (!cursor_above() && highlighted) || need_redraw ) {
                highlighted = 0;
                update(1);
        }
@@ -914,51 +891,49 @@ 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)
-       {
-               if(current->position > position)
-               {
+       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)
-       {
-               if(current->position <= position)
-               {
+       for( current = get_edl()->labels->last ; current; current = PREVIOUS ) {
+               if( current->position <= position ) {
                        start = current;
                        break;
                }
        }
 
 // Select region
-       if(end != start)
-       {
-               if(!start)
-                       mwindow->edl->local_session->set_selectionstart(0);
+       if( end != start ) {
+               if( !start )
+                       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());
+               if( !end )
+                       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);
+       if( end || start ) {
+               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;
 }