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