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