transition length popup rework
[goodguy/cinelerra.git] / cinelerra-5.1 / cinelerra / timebar.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 1997-2014 Adam Williams <broadcast at earthling dot net>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  *
20  */
21
22 #include "awindow.h"
23 #include "awindowgui.h"
24 #include "bcsignals.h"
25 #include "clip.h"
26 #include "cplayback.h"
27 #include "cursors.h"
28 #include "cwindow.h"
29 #include "cwindowgui.h"
30 #include "edl.h"
31 #include "edlsession.h"
32 #include "filexml.h"
33 #include "fonts.h"
34 #include "labels.h"
35 #include "labeledit.h"
36 #include "localsession.h"
37 #include "maincursor.h"
38 #include "mainundo.h"
39 #include "mbuttons.h"
40 #include "mwindow.h"
41 #include "mwindowgui.h"
42 #include "patchbay.h"
43 #include "preferences.h"
44 #include "recordlabel.h"
45 #include "localsession.h"
46 #include "mainsession.h"
47 #include "theme.h"
48 #include "timebar.h"
49 #include "timelinepane.h"
50 #include "trackcanvas.h"
51 #include "tracks.h"
52 #include "transportque.h"
53 #include "units.h"
54 #include "vframe.h"
55 #include "vwindow.h"
56 #include "vwindowgui.h"
57 #include "zoombar.h"
58
59
60 LabelGUI::LabelGUI(MWindow *mwindow, TimeBar *timebar,
61         int64_t pixel, int y,
62         double position, VFrame **data)
63  : BC_Toggle(translate_pixel(mwindow, pixel), y,
64                 data ? data : mwindow->theme->label_toggle, 0)
65 {
66         this->mwindow = mwindow;
67         this->timebar = timebar;
68         this->gui = 0;
69         this->pixel = pixel;
70         this->position = position;
71         this->label = 0;
72 }
73
74 LabelGUI::~LabelGUI()
75 {
76         if( timebar->drag_label == this )
77                 timebar->drag_label = 0;
78 }
79
80 int LabelGUI::get_y(MWindow *mwindow, TimeBar *timebar)
81 {
82         return timebar->get_h() -
83                 mwindow->theme->label_toggle[0]->get_h();
84 }
85
86 int LabelGUI::translate_pixel(MWindow *mwindow, int pixel)
87 {
88         int result = pixel - mwindow->theme->label_toggle[0]->get_w() / 2;
89         return result;
90 }
91
92 void LabelGUI::reposition(int flush)
93 {
94         reposition_window(translate_pixel(mwindow, pixel),
95                 BC_Toggle::get_y());
96 }
97
98 int LabelGUI::button_press_event()
99 {
100         int result = test_drag_label(1);
101
102         if( this->is_event_win() && get_buttonpress() == 3 ) {
103                 if( label ) {
104                         int cur_x, cur_y;
105                         get_abs_cursor(cur_x, cur_y, 0);
106                         timebar->label_edit->start(label, cur_x, cur_y);
107                 }
108                 result = 1;
109         } else {
110                 result = BC_Toggle::button_press_event();
111         }
112         if( label )
113                 set_tooltip(this->label->textstr);
114         return result;
115 }
116
117 int LabelGUI::button_release_event()
118 {
119         int ret = BC_Toggle::button_release_event();
120         test_drag_label(0);
121         return ret;
122 }
123
124 int LabelGUI::test_drag_label(int press)
125 {
126         if( is_event_win() && get_buttonpress() == 1 ) {
127                 switch( timebar->current_operation ) {
128                 case TIMEBAR_NONE:
129                         if( press && get_value() ) {
130                                 timebar->current_operation = TIMEBAR_DRAG_LABEL;
131                                 timebar->drag_label = this;
132                                 set_cursor(HSEPARATE_CURSOR, 0, 0);
133                                 mwindow->undo->update_undo_before(_("drag label"), this);
134                                 return 1;
135                         }
136                         break;
137                 case TIMEBAR_DRAG_LABEL:
138                         if( !press ) {
139                                 timebar->current_operation = TIMEBAR_NONE;
140                                 timebar->drag_label = 0;
141                                 set_cursor(ARROW_CURSOR, 0, 0);
142                                 mwindow->undo->update_undo_after(_("drag label"), LOAD_TIMEBAR);
143                                 mwindow->awindow->gui->async_update_assets(); // labels folder
144                         }
145                         break;
146                 }
147         }
148         return 0;
149 }
150
151 int LabelGUI::handle_event()
152 {
153         timebar->select_label(position);
154         return 1;
155 }
156
157 void LabelGUI::update_value()
158 {
159         EDL *edl = timebar->get_edl();
160         double start = edl->local_session->get_selectionstart(1);
161         double end = edl->local_session->get_selectionend(1);
162         int v = ( label->position >= start && end >= label->position ) ||
163             edl->equivalent(label->position, start) ||
164             edl->equivalent(label->position, end) ||
165             timebar->drag_label == this ? 1 : 0;
166         update(v);
167 }
168
169
170 InPointGUI::InPointGUI(MWindow *mwindow, TimeBar *timebar,
171         int64_t pixel, double position)
172  : LabelGUI(mwindow, timebar,
173         pixel, get_y(mwindow, timebar),
174         position, mwindow->theme->in_point)
175 {
176 //printf("InPointGUI::InPointGUI %d %d\n", pixel, get_y(mwindow, timebar));
177 }
178 InPointGUI::~InPointGUI()
179 {
180 }
181 int InPointGUI::get_y(MWindow *mwindow, TimeBar *timebar)
182 {
183         int result;
184         result = timebar->get_h() -
185                 mwindow->theme->in_point[0]->get_h();
186         return result;
187 }
188
189
190 OutPointGUI::OutPointGUI(MWindow *mwindow, TimeBar *timebar,
191         int64_t pixel, double position)
192  : LabelGUI(mwindow, timebar,
193         pixel, get_y(mwindow, timebar),
194         position, mwindow->theme->out_point)
195 {
196 //printf("OutPointGUI::OutPointGUI %d %d\n", pixel, get_y(mwindow, timebar));
197 }
198 OutPointGUI::~OutPointGUI()
199 {
200 }
201 int OutPointGUI::get_y(MWindow *mwindow, TimeBar *timebar)
202 {
203         return timebar->get_h() -
204                 mwindow->theme->out_point[0]->get_h();
205 }
206
207
208 PresentationGUI::PresentationGUI(MWindow *mwindow, TimeBar *timebar,
209         int64_t pixel, double position)
210  : LabelGUI(mwindow, timebar, pixel, get_y(mwindow, timebar), position)
211 {
212 }
213 PresentationGUI::~PresentationGUI()
214 {
215 }
216
217 TimeBar::TimeBar(MWindow *mwindow, BC_WindowBase *gui,
218         int x, int y, int w, int h)
219  : BC_SubWindow(x, y, w, h)
220 {
221 //printf("TimeBar::TimeBar %d %d %d %d\n", x, y, w, h);
222         this->gui = gui;
223         this->mwindow = mwindow;
224         this->drag_label = 0;
225         label_edit = new LabelEdit(mwindow, mwindow->awindow, 0);
226         pane = 0;
227         highlighted = 0;
228 }
229
230 TimeBar::~TimeBar()
231 {
232         delete in_point;
233         delete out_point;
234         delete label_edit;
235         labels.remove_all_objects();
236         presentations.remove_all_objects();
237 }
238
239 void TimeBar::create_objects()
240 {
241         in_point = 0;
242         out_point = 0;
243 //printf("TimeBar::create_objects %d\n", __LINE__);
244         current_operation = TIMEBAR_NONE;
245         set_cursor(UPRIGHT_ARROW_CURSOR, 0, 0);
246         update(0);
247 }
248
249
250 int64_t TimeBar::position_to_pixel(double position)
251 {
252         get_edl_length();
253         return (int64_t)(position / time_per_pixel);
254 }
255
256
257 double TimeBar::pixel_to_position(int pixel)
258 {
259         if( pane ) {
260                 pixel += get_edl()->local_session->view_start[pane->number];
261         }
262
263         return (double)pixel *
264                 get_edl()->local_session->zoom_sample /
265                 get_edl()->session->sample_rate;
266 }
267
268 void TimeBar::update_labels()
269 {
270         int output = 0;
271         EDL *edl = get_edl();
272
273         if( edl ) {
274                 for( Label *current=edl->labels->first; current; current=NEXT ) {
275                         int64_t pixel = position_to_pixel(current->position);
276                         if( pixel >= 0 && pixel < get_w()  ) {
277 // Create new label
278                                 if( output >= labels.total ) {
279                                         LabelGUI *new_label;
280                                         add_subwindow(new_label =
281                                                 new LabelGUI(mwindow,
282                                                         this,
283                                                         pixel,
284                                                         LabelGUI::get_y(mwindow, this),
285                                                         current->position));
286                                         new_label->set_cursor(INHERIT_CURSOR, 0, 0);
287                                         new_label->set_tooltip(current->textstr);
288                                         new_label->label = current;
289                                         labels.append(new_label);
290                                 }
291                                 else
292 // Reposition old label
293                                 {
294                                         LabelGUI *gui = labels.values[output];
295                                         if( gui->pixel != pixel ) {
296                                                 gui->pixel = pixel;
297                                                 gui->reposition(0);
298                                         }
299 //                                      else {
300 //                                              gui->draw_face(1,0);
301 //                                      }
302
303                                         labels.values[output]->position = current->position;
304                                         labels.values[output]->set_tooltip(current->textstr);
305                                         labels.values[output]->label = current;
306                                 }
307
308                                 labels.values[output++]->update_value();
309                         }
310                 }
311         }
312
313 // Delete excess labels
314         while(labels.total > output)
315         {
316                 labels.remove_object();
317         }
318
319 // Get the labels to show
320         show_window(0);
321 }
322
323 void TimeBar::update_highlights()
324 {
325         EDL *edl = get_edl();
326         if( !edl ) return;
327         for( int i = 0; i < labels.total; i++ ) {
328                 labels.values[i]->update_value();
329         }
330
331         if( edl->equivalent(edl->local_session->get_inpoint(),
332                         edl->local_session->get_selectionstart(1)) ||
333                 edl->equivalent(edl->local_session->get_inpoint(),
334                         edl->local_session->get_selectionend(1)) ) {
335                 if( in_point ) in_point->update(1);
336         }
337         else
338                 if( in_point ) in_point->update(0);
339
340         if( edl->equivalent(edl->local_session->get_outpoint(),
341                         edl->local_session->get_selectionstart(1)) ||
342                 edl->equivalent(edl->local_session->get_outpoint(),
343                         edl->local_session->get_selectionend(1)) ) {
344                 if( out_point ) out_point->update(1);
345         }
346         else
347                 if( out_point ) out_point->update(0);
348
349         draw_inout_highlight();
350 }
351
352 void TimeBar::draw_inout_highlight()
353 {
354         EDL *edl = get_edl();
355         if( !edl->local_session->inpoint_valid() ) return;
356         if( !edl->local_session->outpoint_valid() ) return;
357         double in_position = edl->local_session->get_inpoint();
358         double out_position = edl->local_session->get_outpoint();
359         if( in_position >= out_position ) return;
360         int in_x = position_to_pixel(in_position);
361         int out_x = position_to_pixel(out_position);
362         CLAMP(in_x, 0, get_w());
363         CLAMP(out_x, 0, get_w());
364         set_color(mwindow->theme->inout_highlight_color);
365         int lw = 5;
366         set_line_width(lw);
367         set_inverse();
368         draw_line(in_x, get_h()-2*lw, out_x, get_h()-2*lw);
369         set_opaque();
370         set_line_width(1);
371 }
372
373 void TimeBar::update_points()
374 {
375         EDL *edl = get_edl();
376         int64_t pixel = !edl ? 0 :
377                 position_to_pixel(edl->local_session->get_inpoint());
378
379         if( in_point ) {
380                 if( edl && edl->local_session->inpoint_valid() &&
381                     pixel >= 0 && pixel < get_w() ) {
382                         if( !EQUIV(edl->local_session->get_inpoint(), in_point->position) ||
383                             in_point->pixel != pixel ) {
384                                 in_point->pixel = pixel;
385                                 in_point->position = edl->local_session->get_inpoint();
386                                 in_point->reposition(0);
387                         }
388                         else {
389                                 in_point->draw_face(1, 0);
390                         }
391                 }
392                 else {
393                         delete in_point;
394                         in_point = 0;
395                 }
396         }
397         else
398         if( edl && edl->local_session->inpoint_valid() &&
399             pixel >= 0 && pixel < get_w() ) {
400                 add_subwindow(in_point = new InPointGUI(mwindow,
401                         this, pixel, edl->local_session->get_inpoint()));
402                 in_point->set_cursor(ARROW_CURSOR, 0, 0);
403         }
404
405         pixel = !edl ? 0 :
406                  position_to_pixel(edl->local_session->get_outpoint());
407
408         if( out_point ) {
409                 if( edl && edl->local_session->outpoint_valid() &&
410                     pixel >= 0 && pixel < get_w()) {
411                         if( !EQUIV(edl->local_session->get_outpoint(), out_point->position) ||
412                             out_point->pixel != pixel ) {
413                                 out_point->pixel = pixel;
414                                 out_point->position = edl->local_session->get_outpoint();
415                                 out_point->reposition(0);
416                         }
417                         else {
418                                 out_point->draw_face(1, 0);
419                         }
420                 }
421                 else {
422                         delete out_point;
423                         out_point = 0;
424                 }
425         }
426         else
427         if( edl && edl->local_session->outpoint_valid() &&
428             pixel >= 0 && pixel < get_w() ) {
429                 add_subwindow(out_point = new OutPointGUI(mwindow,
430                         this, pixel, edl->local_session->get_outpoint()));
431                 out_point->set_cursor(ARROW_CURSOR, 0, 0);
432         }
433
434 //      flush();
435 }
436
437 void TimeBar::update_clock(double position)
438 {
439 }
440
441 void TimeBar::update(int flush)
442 {
443         draw_time();
444 // Need to redo these when range is drawn to get the background updated.
445         update_labels();
446         update_points();
447
448
449         EDL *edl = get_edl();
450         int64_t pixel = -1;
451         int x = get_relative_cursor_x();
452 // Draw highlight position
453         if( edl && (highlighted || current_operation == TIMEBAR_DRAG) &&
454             x >= 0 && x < get_w() ) {
455 //printf("TimeBar::update %d %d\n", __LINE__, x);
456                 double position = pixel_to_position(x);
457
458                 position = mwindow->edl->align_to_frame(position, 0);
459                 pixel = position_to_pixel(position);
460                 update_clock(position);
461         }
462
463         if( pixel < 0 ) {
464                 double position = test_highlight();
465                 if( position >= 0 ) pixel = position_to_pixel(position);
466         }
467
468
469         if( pixel >= 0 && pixel < get_w() ) {
470                 set_color(mwindow->theme->timebar_cursor_color);
471                 set_line_dashes(1);
472 //printf("TimeBar::update %d pane=%d pixel=%jd\n", __LINE__, pane->number, pixel);
473                 draw_line(pixel, 0, pixel, get_h());
474                 set_line_dashes(0);
475         }
476
477
478         if( edl ) {
479                 double playback_start = edl->local_session->playback_start;
480                 if( playback_start >= 0 ) {
481                         int64_t pixel = position_to_pixel(playback_start);
482                         set_color(mwindow->theme->timebar_cursor_color ^ 0x0000ff);
483                         draw_line(pixel, 0, pixel, get_h());
484                         double playback_end = edl->local_session->playback_end;
485                         if( playback_end > playback_start ) {
486                                 pixel = position_to_pixel(playback_end);
487                                 set_color(mwindow->theme->timebar_cursor_color ^ 0x00ff00);
488                                 draw_line(pixel, 0, pixel, get_h());
489                         }
490                 }
491
492                 double position = edl->local_session->get_selectionstart(1);
493                 int64_t pixel = position_to_pixel(position);
494 // Draw insertion point position.
495                 int color = mwindow->theme->timebar_cursor_color;
496                 if( mwindow->preferences->forward_render_displacement )
497                         color ^= 0x00ffff;
498                 set_color(color);
499                 draw_line(pixel, 0, pixel, get_h());
500         }
501
502         update_highlights();
503
504 // Get the labels to show
505         show_window(0);
506         flash(flush);
507 //printf("TimeBar::update %d this=%p %d\n", __LINE__, this, current_operation);
508 }
509
510
511
512 int TimeBar::delete_project()
513 {
514 //      labels->delete_all();
515         return 0;
516 }
517
518 int TimeBar::save(FileXML *xml)
519 {
520 //      labels->save(xml);
521         return 0;
522 }
523
524
525
526
527 void TimeBar::draw_time()
528 {
529 }
530
531 EDL* TimeBar::get_edl()
532 {
533         return mwindow->edl;
534 }
535
536
537
538 void TimeBar::draw_range()
539 {
540
541
542 //printf("TimeBar::draw_range %d %p\n", __LINE__, get_edl());
543         if( has_preview() && get_edl() ) {
544                 int x1, x2;
545                 get_preview_pixels(x1, x2);
546
547 //printf("TimeBar::draw_range %f %d %d\n", edl_length, x1, x2);
548                 draw_3segmenth(0, 0, x1, mwindow->theme->timebar_view_data);
549                 draw_top_background(get_parent(), x1, 0, x2 - x1, get_h());
550                 draw_3segmenth(x2, 0, get_w() - x2, mwindow->theme->timebar_view_data);
551
552                 set_color(BLACK);
553                 draw_line(x1, 0, x1, get_h());
554                 draw_line(x2, 0, x2, get_h());
555
556
557                 EDL *edl = get_edl();
558                 if( edl ) {
559                         int64_t pixel = position_to_pixel(
560                                 edl->local_session->get_selectionstart(1));
561 // Draw insertion point position if this timebar belongs to a window which
562 // has something other than the master EDL.
563                         set_color(mwindow->theme->timebar_cursor_color);
564                         draw_line(pixel, 0, pixel, get_h());
565                 }
566         }
567         else
568                 draw_top_background(get_parent(), 0, 0, get_w(), get_h());
569 }
570
571 void TimeBar::select_label(double position)
572 {
573 }
574
575
576
577 int TimeBar::draw()
578 {
579         return 0;
580 }
581
582 double TimeBar::get_edl_length()
583 {
584         edl_length = get_edl() ? get_edl()->tracks->total_length() : 0;
585         int w1 = get_w()-1;
586         time_per_pixel = !EQUIV(edl_length, 0) ? edl_length/w1 : w1;
587         return edl_length;
588 }
589
590 int TimeBar::get_preview_pixels(int &x1, int &x2)
591 {
592         x1 = 0;  x2 = get_w();
593         get_edl_length();
594         EDL *edl = get_edl();
595         if( edl && !EQUIV(edl_length, 0) ) {
596                 double preview_start = edl->local_session->preview_start;
597                 double preview_end = edl->local_session->preview_end;
598                 if( preview_end < 0 || preview_end > edl_length )
599                         preview_end = edl_length;
600                 if( preview_end >= preview_start ) {
601                         x1 = (int)(preview_start / time_per_pixel);
602                         x2 = (int)(preview_end / time_per_pixel);
603                 }
604         }
605         return 0;
606 }
607
608
609 int TimeBar::test_preview(int buttonpress)
610 {
611         int result = 0;
612
613
614         if( get_edl() && cursor_inside() && buttonpress >= 0 ) {
615                 int x1, x2, x = get_relative_cursor_x();
616                 get_preview_pixels(x1, x2);
617 //printf("TimeBar::test_preview %d %d %d\n", x1, x2, x);
618 // Inside left handle
619                 if( x >= x1 - HANDLE_W && x < x1 + HANDLE_W &&
620 // Ignore left handle if both handles are up against the left side
621                     x2 > HANDLE_W ) {
622                         if( buttonpress ) {
623                                 current_operation = TIMEBAR_DRAG_LEFT;
624                                 start_position = get_edl()->local_session->preview_start;
625                                 start_cursor_x = x;
626                         }
627                         else if( get_cursor() != LEFT_CURSOR )
628                                 set_cursor(LEFT_CURSOR, 0, 1);
629                         result = 1;
630                 }
631 // Inside right handle
632                 else if( x >= x2 - HANDLE_W && x < x2 + HANDLE_W &&
633 // Ignore right handle if both handles are up against the right side
634                     x1 < get_w() - HANDLE_W ) {
635                         if( buttonpress ) {
636                                 current_operation = TIMEBAR_DRAG_RIGHT;
637                                 start_position = get_edl()->local_session->preview_end;
638                                 if( start_position < 0 || start_position > edl_length )
639                                         start_position = edl_length;
640                                 start_cursor_x = x;
641                         }
642                         else if( get_cursor() != RIGHT_CURSOR )
643                                 set_cursor(RIGHT_CURSOR, 0, 1);
644                         result = 1;
645                 }
646 // Inside preview
647                 else if( get_button_down() && get_buttonpress() == 3 &&
648                     x >= x1 && x < x2 ) {
649                         if( buttonpress ) {
650                                 current_operation = TIMEBAR_DRAG_CENTER;
651                                 starting_start_position = get_edl()->local_session->preview_start;
652                                 starting_end_position = get_edl()->local_session->preview_end;
653                                 if( starting_end_position < 0 || starting_end_position > edl_length )
654                                         starting_end_position = edl_length;
655                                 start_cursor_x = x;
656                         }
657                         if( get_cursor() != HSEPARATE_CURSOR )
658                                 set_cursor(HSEPARATE_CURSOR, 0, 1);
659                         result = 1;
660                 }
661         }
662
663         if( !result && get_cursor() != ARROW_CURSOR )
664                 set_cursor(ARROW_CURSOR, 0, 1);
665
666
667         return result;
668 }
669
670 int TimeBar::move_preview(int &redraw)
671 {
672         int result = 0, x = get_relative_cursor_x();
673         switch( current_operation ) {
674         case TIMEBAR_DRAG_LEFT: {
675                 get_edl()->local_session->preview_start =
676                         start_position + time_per_pixel * (x - start_cursor_x);
677                 double preview_end = get_edl()->local_session->preview_end;
678                 if( preview_end < 0 || preview_end > edl_length )
679                         preview_end = get_edl()->local_session->preview_end = edl_length;
680                 CLAMP(get_edl()->local_session->preview_start, 0, preview_end);
681                 result = 1;
682                 break; }
683         case TIMEBAR_DRAG_RIGHT: {
684                 double preview_end = get_edl()->local_session->preview_end =
685                         start_position + time_per_pixel * (x - start_cursor_x);
686                 double preview_start = get_edl()->local_session->preview_start;
687                 if( preview_end >= edl_length && !preview_start ) {
688                         get_edl()->local_session->preview_end = -1;
689                         if( preview_start > preview_end )
690                                 preview_start = get_edl()->local_session->preview_start = preview_end;
691                 }
692                 else
693                         CLAMP(get_edl()->local_session->preview_end, preview_start, edl_length);
694                 result = 1;
695                 break; }
696         case TIMEBAR_DRAG_CENTER: {
697                 double dt = time_per_pixel * (x - start_cursor_x);
698                 get_edl()->local_session->preview_start = starting_start_position + dt;
699                 get_edl()->local_session->preview_end = starting_end_position + dt;
700                 if( get_edl()->local_session->preview_start < 0 ) {
701                         get_edl()->local_session->preview_end -= get_edl()->local_session->preview_start;
702                         get_edl()->local_session->preview_start = 0;
703                 }
704                 else
705                 if( get_edl()->local_session->preview_end > edl_length ) {
706                         get_edl()->local_session->preview_start -= get_edl()->local_session->preview_end - edl_length;
707                         get_edl()->local_session->preview_end = edl_length;
708                 }
709                 result = 1;
710                 break; }
711         }
712
713 //printf("TimeBar::move_preview %d %d\n", __LINE__, current_operation);
714
715         if( result ) {
716                 update_preview();
717                 redraw = 1;
718         }
719 //printf("TimeBar::move_preview %d %d\n", __LINE__, current_operation);
720
721         return result;
722 }
723
724 void TimeBar::update_preview()
725 {
726 }
727
728 int TimeBar::samplemovement()
729 {
730         return 0;
731 }
732
733 void TimeBar::stop_playback()
734 {
735 }
736
737 int TimeBar::button_press_event()
738 {
739         int result = 0;
740         if( is_event_win() && cursor_above() ) {
741                 if( has_preview() && get_buttonpress() == 3 ) {
742                         result = test_preview(1);
743                 }
744 // Change time format
745                 else if( !is_vwindow() && ctrl_down() ) {
746                         if( get_buttonpress() == 1 )
747                                 mwindow->next_time_format();
748                         else
749                         if( get_buttonpress() == 2 )
750                                 mwindow->prev_time_format();
751                         result = 1;
752                 }
753                 else if( get_buttonpress() == 1 ) {
754                         stop_playback();
755
756 // Select region between two labels
757                         if( !is_vwindow() && get_double_click() ) {
758                                 int x = get_relative_cursor_x();
759                                 double position = pixel_to_position(x);
760 // Test labels
761                                 select_region(position);
762                         }
763                         else {
764
765 // Reposition highlight cursor
766                                 update_cursor();
767                                 current_operation = TIMEBAR_DRAG;
768                                 activate_timeline();
769                         }
770                         result = 1;
771                 }
772         }
773         return result;
774 }
775
776 void TimeBar::activate_timeline()
777 {
778         mwindow->gui->activate_timeline();
779 }
780
781 int TimeBar::cursor_motion_event()
782 {
783         int result = 0;
784         int redraw = 0;
785
786         switch( current_operation ) {
787         case TIMEBAR_DRAG_LEFT:
788         case TIMEBAR_DRAG_RIGHT:
789         case TIMEBAR_DRAG_CENTER:
790                 if( has_preview() )
791                         result = move_preview(redraw);
792                 break;
793
794         case TIMEBAR_DRAG_LABEL:
795                 if( drag_label ) {
796                         EDL *edl = get_edl();
797                         int pixel = get_relative_cursor_x();
798                         double position = pixel_to_position(pixel);
799                         if( drag_label->label )
800                                 drag_label->label->position = position;
801                         else if( drag_label == in_point ) {
802                                 if( out_point && edl->local_session->outpoint_valid() ) {
803                                         double out_pos = edl->local_session->get_outpoint();
804                                         if( position > out_pos ) {
805                                                 edl->local_session->set_outpoint(position);
806                                                 drag_label = out_point;
807                                                 position = out_pos;
808                                         }
809                                 }
810                                 edl->local_session->set_inpoint(position);
811                         }
812                         else if( drag_label == out_point ) {
813                                 if( in_point && edl->local_session->inpoint_valid() ) {
814                                         double in_pos = edl->local_session->get_inpoint();
815                                         if( position < in_pos ) {
816                                                 edl->local_session->set_inpoint(position);
817                                                 drag_label = in_point;
818                                                 position = in_pos;
819                                         }
820                                 }
821                                 edl->local_session->set_outpoint(position);
822                         }
823                 }
824         // fall thru
825         case TIMEBAR_DRAG:
826                 update_cursor();
827                 handle_mwindow_drag();
828                 result = 1;
829                 break;
830
831         default:
832                 if( has_preview() )
833                         result = test_preview(0);
834                 break;
835         }
836
837
838         if( redraw ) {
839                 update(1);
840         }
841
842         return result;
843 }
844
845 int TimeBar::cursor_leave_event()
846 {
847         if( highlighted ) {
848                 highlighted = 0;
849                 update(1);
850         }
851         return 0;
852 }
853
854 int TimeBar::button_release_event()
855 {
856 //printf("TimeBar::button_release_event %d %d\n", __LINE__, current_operation);
857         int result = 0;
858         int need_redraw = 0;
859         switch( current_operation )
860         {
861                 case TIMEBAR_DRAG:
862                         mwindow->gui->get_focused_pane()->canvas->stop_dragscroll();
863                         current_operation = TIMEBAR_NONE;
864                         need_redraw = 1;
865                         result = 1;
866                         break;
867
868                 default:
869                         if( current_operation != TIMEBAR_NONE ) {
870                                 current_operation = TIMEBAR_NONE;
871                                 result = 1;
872                         }
873                         break;
874         }
875
876         if( (!cursor_above() && highlighted) || need_redraw ) {
877                 highlighted = 0;
878                 update(1);
879         }
880
881         return result;
882 }
883
884 // Update the selection cursor during a dragging operation
885 void TimeBar::update_cursor()
886 {
887 }
888
889 void TimeBar::handle_mwindow_drag()
890 {
891 }
892
893 int TimeBar::select_region(double position)
894 {
895         Label *start = 0, *end = 0, *current;
896         for( current = get_edl()->labels->first; current; current = NEXT ) {
897                 if( current->position > position ) {
898                         end = current;
899                         break;
900                 }
901         }
902
903         for( current = get_edl()->labels->last ; current; current = PREVIOUS ) {
904                 if( current->position <= position ) {
905                         start = current;
906                         break;
907                 }
908         }
909
910 // Select region
911         if( end != start ) {
912                 if( !start )
913                         get_edl()->local_session->set_selectionstart(0);
914                 else
915                         get_edl()->local_session->set_selectionstart(start->position);
916
917                 if( !end )
918                         get_edl()->local_session->set_selectionend(get_edl()->tracks->total_length());
919                 else
920                         get_edl()->local_session->set_selectionend(end->position);
921         }
922         else
923         if( end || start ) {
924                 get_edl()->local_session->set_selectionstart(start->position);
925                 get_edl()->local_session->set_selectionend(start->position);
926         }
927
928 // Que the CWindow
929         mwindow->cwindow->gui->lock_window("TimeBar::select_region");
930         mwindow->cwindow->update(1, 0, 0);
931         mwindow->cwindow->gui->unlock_window();
932         mwindow->gui->lock_window("TimeBar::select_region");
933         mwindow->gui->hide_cursor(0);
934         mwindow->gui->draw_cursor(1);
935         mwindow->gui->flash_canvas(0);
936         mwindow->gui->activate_timeline();
937         mwindow->gui->zoombar->update();
938         mwindow->gui->unlock_window();
939         update_highlights();
940         return 0;
941 }
942
943
944
945
946 int TimeBar::delete_arrows()
947 {
948         return 0;
949 }
950
951 double TimeBar::test_highlight()
952 {
953         return -1;
954 }
955
956