4 * Copyright (C) 1997-2014 Adam Williams <broadcast at earthling dot net>
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.
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.
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
22 #include "bcsignals.h"
24 #include "cplayback.h"
28 #include "edlsession.h"
32 #include "localsession.h"
33 #include "maincursor.h"
37 #include "mwindowgui.h"
39 #include "preferences.h"
40 #include "recordlabel.h"
41 #include "localsession.h"
42 #include "mainsession.h"
45 #include "timelinepane.h"
46 #include "trackcanvas.h"
48 #include "transportque.h"
52 #include "vwindowgui.h"
56 LabelGUI::LabelGUI(MWindow *mwindow,
62 : BC_Toggle(translate_pixel(mwindow, pixel),
64 data ? data : mwindow->theme->label_toggle,
67 this->mwindow = mwindow;
68 this->timebar = timebar;
71 this->position = position;
78 int LabelGUI::get_y(MWindow *mwindow, TimeBar *timebar)
80 return timebar->get_h() -
81 mwindow->theme->label_toggle[0]->get_h();
84 int LabelGUI::translate_pixel(MWindow *mwindow, int pixel)
86 int result = pixel - mwindow->theme->label_toggle[0]->get_w() / 2;
90 void LabelGUI::reposition(int flush)
92 reposition_window(translate_pixel(mwindow, pixel),
96 int LabelGUI::handle_event()
98 timebar->select_label(position);
109 InPointGUI::InPointGUI(MWindow *mwindow,
116 get_y(mwindow, timebar),
118 mwindow->theme->in_point)
120 //printf("InPointGUI::InPointGUI %d %d\n", pixel, get_y(mwindow, timebar));
122 InPointGUI::~InPointGUI()
125 int InPointGUI::get_y(MWindow *mwindow, TimeBar *timebar)
128 result = timebar->get_h() -
129 mwindow->theme->in_point[0]->get_h();
134 OutPointGUI::OutPointGUI(MWindow *mwindow,
141 get_y(mwindow, timebar),
143 mwindow->theme->out_point)
145 //printf("OutPointGUI::OutPointGUI %d %d\n", pixel, get_y(mwindow, timebar));
147 OutPointGUI::~OutPointGUI()
150 int OutPointGUI::get_y(MWindow *mwindow, TimeBar *timebar)
152 return timebar->get_h() -
153 mwindow->theme->out_point[0]->get_h();
157 PresentationGUI::PresentationGUI(MWindow *mwindow,
161 : LabelGUI(mwindow, timebar, pixel, get_y(mwindow, timebar), position)
164 PresentationGUI::~PresentationGUI()
174 TimeBar::TimeBar(MWindow *mwindow,
180 : BC_SubWindow(x, y, w, h)
182 //printf("TimeBar::TimeBar %d %d %d %d\n", x, y, w, h);
184 this->mwindow = mwindow;
191 if(in_point) delete in_point;
192 if(out_point) delete out_point;
193 labels.remove_all_objects();
194 presentations.remove_all_objects();
197 void TimeBar::create_objects()
201 //printf("TimeBar::create_objects %d\n", __LINE__);
202 current_operation = TIMEBAR_NONE;
203 set_cursor(UPRIGHT_ARROW_CURSOR, 0, 0);
208 int64_t TimeBar::position_to_pixel(double position)
211 return (int64_t)(position / time_per_pixel);
215 double TimeBar::pixel_to_position(int pixel)
219 pixel += mwindow->edl->local_session->view_start[pane->number];
222 return (double)pixel *
223 mwindow->edl->local_session->zoom_sample /
224 mwindow->edl->session->sample_rate;
227 void TimeBar::update_labels()
230 EDL *edl = get_edl();
234 for(Label *current = edl->labels->first;
238 int64_t pixel = position_to_pixel(current->position);
240 if(pixel >= 0 && pixel < get_w())
243 if(output >= labels.total)
246 add_subwindow(new_label =
247 new LabelGUI(mwindow,
250 LabelGUI::get_y(mwindow, this),
252 new_label->set_cursor(INHERIT_CURSOR, 0, 0);
253 labels.append(new_label);
256 // Reposition old label
258 LabelGUI *gui = labels.values[output];
259 if(gui->pixel != pixel)
269 labels.values[output]->position = current->position;
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);
276 if(labels.values[output]->get_value())
277 labels.values[output]->update(0);
284 // Delete excess labels
285 while(labels.total > output)
287 labels.remove_object();
290 // Get the labels to show
294 void TimeBar::update_highlights()
296 for(int i = 0; i < labels.total; i++)
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)))
304 if(!label->get_value()) label->update(1);
307 if(label->get_value()) label->update(0);
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)))
315 if(in_point) in_point->update(1);
318 if(in_point) in_point->update(0);
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)))
325 if(out_point) out_point->update(1);
328 if(out_point) out_point->update(0);
331 void TimeBar::update_points()
333 EDL *edl = get_edl();
334 int64_t pixel = !edl ? 0 :
335 position_to_pixel(edl->local_session->get_inpoint());
340 edl->local_session->inpoint_valid() &&
341 pixel >= 0 && pixel < get_w())
343 if(!EQUIV(edl->local_session->get_inpoint(), in_point->position) ||
344 in_point->pixel != pixel)
346 in_point->pixel = pixel;
347 in_point->position = edl->local_session->get_inpoint();
348 in_point->reposition(0);
352 in_point->draw_face(1, 0);
362 if(edl && edl->local_session->inpoint_valid() &&
363 pixel >= 0 && pixel < get_w())
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);
371 position_to_pixel(edl->local_session->get_outpoint());
375 if( edl && edl->local_session->outpoint_valid() &&
376 pixel >= 0 && pixel < get_w())
378 if(!EQUIV(edl->local_session->get_outpoint(), out_point->position) ||
379 out_point->pixel != pixel)
381 out_point->pixel = pixel;
382 out_point->position = edl->local_session->get_outpoint();
383 out_point->reposition(0);
387 out_point->draw_face(1, 0);
398 edl->local_session->outpoint_valid() &&
399 pixel >= 0 && pixel < get_w())
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);
409 void TimeBar::update_clock(double position)
413 void TimeBar::update(int flush)
416 // Need to redo these when range is drawn to get the background updated.
421 EDL *edl = get_edl();
423 int x = get_relative_cursor_x();
424 // Draw highlight position
426 (highlighted || current_operation == TIMEBAR_DRAG) &&
427 x >= 0 && x < get_w())
429 //printf("TimeBar::update %d %d\n", __LINE__, x);
430 double position = pixel_to_position(x);
432 position = get_edl()->align_to_frame(position, 0);
433 pixel = position_to_pixel(position);
434 update_clock(position);
439 double position = test_highlight();
440 if(position >= 0) pixel = position_to_pixel(position);
444 if(pixel >= 0 && pixel < get_w())
446 set_color(mwindow->theme->timebar_cursor_color);
448 //printf("TimeBar::update %d pane=%d pixel=%jd\n", __LINE__, pane->number, pixel);
449 draw_line(pixel, 0, pixel, get_h());
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());
465 // Get the labels to show
468 //printf("TimeBar::update %d this=%p %d\n", __LINE__, this, current_operation);
473 int TimeBar::delete_project()
475 // labels->delete_all();
479 int TimeBar::save(FileXML *xml)
481 // labels->save(xml);
488 void TimeBar::draw_time()
492 EDL* TimeBar::get_edl()
499 void TimeBar::draw_range()
503 //printf("TimeBar::draw_range %d %p\n", __LINE__, get_edl());
504 if(has_preview() && get_edl())
507 get_preview_pixels(x1, x2);
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);
515 draw_line(x1, 0, x1, get_h());
516 draw_line(x2, 0, x2, get_h());
519 EDL *edl = get_edl();
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());
531 draw_top_background(get_parent(), 0, 0, get_w(), get_h());
534 void TimeBar::select_label(double position)
545 double TimeBar::get_edl_length()
551 //printf("TimeBar::get_edl_length 1 %f\n", get_edl()->tracks->total_playable_length());
552 edl_length = get_edl()->tracks->total_playable_length();
555 //printf("TimeBar::get_edl_length 2\n");
556 if(!EQUIV(edl_length, 0))
558 //printf("TimeBar::get_edl_length 3\n");
559 time_per_pixel = edl_length / get_w();
560 //printf("TimeBar::get_edl_length 4\n");
566 //printf("TimeBar::get_edl_length 5\n");
571 int TimeBar::get_preview_pixels(int &x1, int &x2)
580 if(!EQUIV(edl_length, 0))
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);
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,
606 int TimeBar::test_preview(int buttonpress)
611 if(get_edl() && cursor_inside() && buttonpress >= 0)
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
623 current_operation = TIMEBAR_DRAG_LEFT;
624 start_position = get_edl()->local_session->preview_start;
627 else if(get_cursor() != LEFT_CURSOR)
628 set_cursor(LEFT_CURSOR, 0, 1);
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)
638 current_operation = TIMEBAR_DRAG_RIGHT;
639 start_position = get_edl()->local_session->preview_end;
642 else if(get_cursor() != RIGHT_CURSOR)
643 set_cursor(RIGHT_CURSOR, 0, 1);
647 else if(get_button_down() && get_buttonpress() == 3 &&
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;
657 if(get_cursor() != HSEPARATE_CURSOR)
658 set_cursor(HSEPARATE_CURSOR, 0, 1);
663 if(!result && get_cursor() != ARROW_CURSOR)
664 set_cursor(ARROW_CURSOR, 0, 1);
670 int TimeBar::move_preview(int &redraw)
672 int result = 0, x = get_relative_cursor_x();
674 if(current_operation == TIMEBAR_DRAG_LEFT)
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,
680 get_edl()->local_session->preview_end);
684 if(current_operation == TIMEBAR_DRAG_RIGHT)
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,
694 if(current_operation == 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)
701 get_edl()->local_session->preview_end -= get_edl()->local_session->preview_start;
702 get_edl()->local_session->preview_start = 0;
705 if(get_edl()->local_session->preview_end > edl_length)
707 get_edl()->local_session->preview_start -= get_edl()->local_session->preview_end - edl_length;
708 get_edl()->local_session->preview_end = edl_length;
713 //printf("TimeBar::move_preview %d %d\n", __LINE__, current_operation);
720 //printf("TimeBar::move_preview %d %d\n", __LINE__, current_operation);
725 void TimeBar::update_preview()
729 int TimeBar::samplemovement()
734 void TimeBar::stop_playback()
738 int TimeBar::button_press_event()
741 if(is_event_win() && cursor_above())
743 if(has_preview() && get_buttonpress() == 3)
745 result = test_preview(1);
747 // Change time format
750 if(get_buttonpress() == 1)
751 mwindow->next_time_format();
753 if(get_buttonpress() == 2)
754 mwindow->prev_time_format();
757 else if(get_buttonpress() == 1)
761 // Select region between two labels
762 if(get_double_click())
764 int x = get_relative_cursor_x();
765 double position = pixel_to_position(x);
767 select_region(position);
772 // Reposition highlight cursor
774 current_operation = TIMEBAR_DRAG;
783 void TimeBar::activate_timeline()
785 mwindow->gui->activate_timeline();
788 int TimeBar::cursor_motion_event()
793 //printf("TimeBar::cursor_motion_event %d %p %d\n", __LINE__, this, current_operation);
794 switch(current_operation)
799 handle_mwindow_drag();
801 //printf("TimeBar::cursor_motion_event %d %d\n", __LINE__, current_operation);
806 case TIMEBAR_DRAG_LEFT:
807 case TIMEBAR_DRAG_RIGHT:
808 case TIMEBAR_DRAG_CENTER:
810 result = move_preview(redraw);
820 //printf("TimeBar::cursor_motion_event 20\n");
822 result = test_preview(0);
823 //printf("TimeBar::cursor_motion_event 30\n");
828 //printf("TimeBar::cursor_motion_event %d %d\n", __LINE__, current_operation);
833 //printf("TimeBar::cursor_motion_event %d %p %d\n", __LINE__, this, current_operation);
838 int TimeBar::cursor_leave_event()
848 int TimeBar::button_release_event()
850 //printf("TimeBar::button_release_event %d %d\n", __LINE__, current_operation);
853 switch(current_operation)
856 mwindow->gui->get_focused_pane()->canvas->stop_dragscroll();
857 current_operation = TIMEBAR_NONE;
863 if(current_operation != TIMEBAR_NONE)
865 current_operation = TIMEBAR_NONE;
871 if((!cursor_above() && highlighted) || need_redraw)
880 // Update the selection cursor during a dragging operation
881 void TimeBar::update_cursor()
885 void TimeBar::handle_mwindow_drag()
889 int TimeBar::select_region(double position)
891 Label *start = 0, *end = 0, *current;
892 for(current = mwindow->edl->labels->first; current; current = NEXT)
894 if(current->position > position)
901 for(current = mwindow->edl->labels->last ; current; current = PREVIOUS)
903 if(current->position <= position)
914 mwindow->edl->local_session->set_selectionstart(0);
916 mwindow->edl->local_session->set_selectionstart(start->position);
919 mwindow->edl->local_session->set_selectionend(mwindow->edl->tracks->total_length());
921 mwindow->edl->local_session->set_selectionend(end->position);
926 mwindow->edl->local_session->set_selectionstart(start->position);
927 mwindow->edl->local_session->set_selectionend(start->position);
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();
944 int TimeBar::delete_arrows()
949 double TimeBar::test_highlight()