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