4 * Copyright (C) 1997-2011 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
24 #include "awindowgui.h"
30 #include "edlsession.h"
31 #include "filesystem.h"
37 #include "localsession.h"
38 #include "mainclock.h"
40 #include "mainsession.h"
42 #include "meterpanel.h"
43 #include "mwindowgui.h"
45 #include "playtransport.h"
46 #include "preferences.h"
51 #include "vplayback.h"
53 #include "vwindowgui.h"
59 VWindowGUI::VWindowGUI(MWindow *mwindow, VWindow *vwindow)
60 : BC_Window(PROGRAM_NAME ": Viewer",
61 mwindow->session->vwindow_x,
62 mwindow->session->vwindow_y,
63 mwindow->session->vwindow_w,
64 mwindow->session->vwindow_h,
71 this->mwindow = mwindow;
72 this->vwindow = vwindow;
80 VWindowGUI::~VWindowGUI()
82 sources.remove_all_objects();
83 labels.remove_all_objects();
91 void VWindowGUI::change_source(EDL *edl, const char *title)
93 //printf("VWindowGUI::change_source %d\n", __LINE__);
95 update_sources(title);
96 char string[BCTEXTLEN];
99 sprintf(string, PROGRAM_NAME ": %s", title);
101 sprintf(string, PROGRAM_NAME ": Viewer");
103 lock_window("VWindowGUI::change_source");
110 // Get source list from master EDL
111 void VWindowGUI::update_sources(const char *title)
113 lock_window("VWindowGUI::update_sources");
115 //printf("VWindowGUI::update_sources 1\n");
116 sources.remove_all_objects();
117 //printf("VWindowGUI::update_sources 2\n");
122 i < mwindow->edl->clips.total;
125 char *clip_title = mwindow->edl->clips.values[i]->local_session->clip_title;
128 for(int j = 0; j < sources.total; j++)
130 if(!strcasecmp(sources.values[j]->get_text(), clip_title))
138 sources.append(new BC_ListBoxItem(clip_title));
141 //printf("VWindowGUI::update_sources 3\n");
144 for(Asset *current = mwindow->edl->assets->first;
148 char clip_title[BCTEXTLEN];
149 fs.extract_name(clip_title, current->path);
152 for(int j = 0; j < sources.total; j++)
154 if(!strcasecmp(sources.values[j]->get_text(), clip_title))
162 sources.append(new BC_ListBoxItem(clip_title));
166 //printf("VWindowGUI::update_sources 4\n");
168 // source->update_list(&sources);
169 // source->update(title);
173 void VWindowGUI::create_objects()
177 lock_window("VWindowGUI::create_objects");
178 set_icon(mwindow->theme->get_image("vwindow_icon"));
180 //printf("VWindowGUI::create_objects 1\n");
181 mwindow->theme->get_vwindow_sizes(this);
182 mwindow->theme->draw_vwindow_bg(this);
185 meters = new VWindowMeters(mwindow,
187 mwindow->theme->vmeter_x,
188 mwindow->theme->vmeter_y,
189 mwindow->theme->vmeter_h);
190 meters->create_objects();
192 //printf("VWindowGUI::create_objects 1\n");
193 // Requires meters to build
194 edit_panel = new VWindowEditing(mwindow, vwindow);
195 edit_panel->set_meters(meters);
196 edit_panel->create_objects();
198 //printf("VWindowGUI::create_objects 1\n");
199 transport = new VWindowTransport(mwindow,
201 mwindow->theme->vtransport_x,
202 mwindow->theme->vtransport_y);
203 transport->create_objects();
205 //printf("VWindowGUI::create_objects 1\n");
206 // add_subwindow(fps_title = new BC_Title(mwindow->theme->vedit_x, y, ""));
207 add_subwindow(clock = new MainClock(mwindow,
208 mwindow->theme->vtime_x,
209 mwindow->theme->vtime_y,
210 mwindow->theme->vtime_w));
212 canvas = new VWindowCanvas(mwindow, this);
213 canvas->create_objects(mwindow->edl);
214 canvas->use_vwindow();
217 //printf("VWindowGUI::create_objects 1\n");
218 add_subwindow(timebar = new VTimeBar(mwindow,
220 mwindow->theme->vtimebar_x,
221 mwindow->theme->vtimebar_y,
222 mwindow->theme->vtimebar_w,
223 mwindow->theme->vtimebar_h));
224 timebar->create_objects();
225 //printf("VWindowGUI::create_objects 2\n");
228 //printf("VWindowGUI::create_objects 1\n");
229 // source = new VWindowSource(mwindow,
231 // mwindow->theme->vsource_x,
232 // mwindow->theme->vsource_y);
233 // source->create_objects();
234 update_sources(_("None"));
236 //printf("VWindowGUI::create_objects 2\n");
243 int VWindowGUI::resize_event(int w, int h)
245 mwindow->session->vwindow_x = get_x();
246 mwindow->session->vwindow_y = get_y();
247 mwindow->session->vwindow_w = w;
248 mwindow->session->vwindow_h = h;
250 mwindow->theme->get_vwindow_sizes(this);
251 mwindow->theme->draw_vwindow_bg(this);
254 //printf("VWindowGUI::resize_event %d %d\n", __LINE__, mwindow->theme->vedit_y);
255 edit_panel->reposition_buttons(mwindow->theme->vedit_x,
256 mwindow->theme->vedit_y);
258 timebar->resize_event();
259 transport->reposition_buttons(mwindow->theme->vtransport_x,
260 mwindow->theme->vtransport_y);
261 clock->reposition_window(mwindow->theme->vtime_x,
262 mwindow->theme->vtime_y,
263 mwindow->theme->vtime_w,
265 canvas->reposition_window(0,
266 mwindow->theme->vcanvas_x,
267 mwindow->theme->vcanvas_y,
268 mwindow->theme->vcanvas_w,
269 mwindow->theme->vcanvas_h);
270 //printf("VWindowGUI::resize_event %d %d\n", __LINE__, mwindow->theme->vcanvas_x);
271 // source->reposition_window(mwindow->theme->vsource_x,
272 // mwindow->theme->vsource_y);
273 meters->reposition_window(mwindow->theme->vmeter_x,
274 mwindow->theme->vmeter_y,
276 mwindow->theme->vmeter_h);
278 BC_WindowBase::resize_event(w, h);
286 int VWindowGUI::translation_event()
288 mwindow->session->vwindow_x = get_x();
289 mwindow->session->vwindow_y = get_y();
293 int VWindowGUI::close_event()
296 int i = mwindow->vwindows.size();
297 while( --i >= 0 && mwindow->vwindows.get(i)->gui != this );
303 mwindow->session->show_vwindow = 0;
306 mwindow->gui->lock_window("VWindowGUI::close_event");
307 mwindow->gui->mainmenu->show_vwindow->set_checked(0);
308 mwindow->gui->unlock_window();
310 lock_window("VWindowGUI::close_event");
311 mwindow->save_defaults();
315 int VWindowGUI::keypress_event()
318 switch(get_keypress())
326 mwindow->undo_entry(this);
329 mwindow->redo_entry(this);
333 if(mwindow->session->vwindow_fullscreen)
334 canvas->stop_fullscreen();
336 canvas->start_fullscreen();
337 lock_window("VWindowGUI::keypress_event 1");
341 if(mwindow->session->vwindow_fullscreen)
342 canvas->stop_fullscreen();
343 lock_window("VWindowGUI::keypress_event 2");
346 if(!result) result = transport->keypress_event();
351 int VWindowGUI::button_press_event()
353 if(canvas->get_canvas())
354 return canvas->button_press_event_base(canvas->get_canvas());
358 int VWindowGUI::cursor_leave_event()
360 if(canvas->get_canvas())
361 return canvas->cursor_leave_event_base(canvas->get_canvas());
365 int VWindowGUI::cursor_enter_event()
367 if(canvas->get_canvas())
368 return canvas->cursor_enter_event_base(canvas->get_canvas());
372 int VWindowGUI::button_release_event()
374 if(canvas->get_canvas())
375 return canvas->button_release_event();
379 int VWindowGUI::cursor_motion_event()
381 if(canvas->get_canvas())
383 canvas->get_canvas()->unhide_cursor();
384 return canvas->cursor_motion_event();
390 void VWindowGUI::drag_motion()
393 if(get_hidden()) return;
394 if(mwindow->session->current_operation != DRAG_ASSET) return;
396 int old_status = mwindow->session->vcanvas_highlighted;
398 int cursor_x = get_relative_cursor_x();
399 int cursor_y = get_relative_cursor_y();
401 mwindow->session->vcanvas_highlighted = (get_cursor_over_window() &&
402 cursor_x >= canvas->x &&
403 cursor_x < canvas->x + canvas->w &&
404 cursor_y >= canvas->y &&
405 cursor_y < canvas->y + canvas->h);
408 printf("VWindowGUI::drag_motion 1 %d %d %d %d %d\n",
410 mwindow->session->vcanvas_highlighted,
411 get_cursor_over_window(),
416 if(old_status != mwindow->session->vcanvas_highlighted)
417 canvas->draw_refresh();
420 int VWindowGUI::drag_stop()
422 if(get_hidden()) return 0;
424 if(mwindow->session->vcanvas_highlighted &&
425 mwindow->session->current_operation == DRAG_ASSET)
427 mwindow->session->vcanvas_highlighted = 0;
428 canvas->draw_refresh();
430 Indexable *indexable = mwindow->session->drag_assets->size() ?
431 mwindow->session->drag_assets->get(0) :
433 EDL *edl = mwindow->session->drag_clips->size() ?
434 mwindow->session->drag_clips->get(0) :
438 vwindow->change_source(indexable);
441 vwindow->change_source(edl);
449 void VWindowGUI::update_meters()
451 if(mwindow->edl->session->vwindow_meter != meters->visible)
453 meters->set_meters(meters->meter_count,
454 mwindow->edl->session->vwindow_meter);
455 mwindow->theme->get_vwindow_sizes(this);
456 resize_event(get_w(), get_h());
462 VWindowMeters::VWindowMeters(MWindow *mwindow,
467 : MeterPanel(mwindow,
473 mwindow->edl->session->audio_channels,
474 mwindow->edl->session->vwindow_meter,
478 this->mwindow = mwindow;
482 VWindowMeters::~VWindowMeters()
486 int VWindowMeters::change_status_event(int new_status)
488 mwindow->edl->session->vwindow_meter = new_status;
489 gui->update_meters();
499 VWindowEditing::VWindowEditing(MWindow *mwindow, VWindow *vwindow)
502 mwindow->theme->vedit_x,
503 mwindow->theme->vedit_y,
522 this->mwindow = mwindow;
523 this->vwindow = vwindow;
526 VWindowEditing::~VWindowEditing()
530 void VWindowEditing::copy_selection()
535 void VWindowEditing::splice_selection()
537 if(vwindow->get_edl())
539 mwindow->gui->lock_window("VWindowEditing::splice_selection");
540 mwindow->splice(vwindow->get_edl());
541 mwindow->gui->unlock_window();
545 void VWindowEditing::overwrite_selection()
547 if(vwindow->get_edl())
549 mwindow->gui->lock_window("VWindowEditing::overwrite_selection");
550 mwindow->overwrite(vwindow->get_edl());
551 mwindow->gui->unlock_window();
555 void VWindowEditing::toggle_label()
557 if(vwindow->get_edl())
559 EDL *edl = vwindow->get_edl();
560 edl->labels->toggle_label(edl->local_session->get_selectionstart(1),
561 edl->local_session->get_selectionend(1));
562 vwindow->gui->timebar->update(1);
566 void VWindowEditing::prev_label()
568 if(vwindow->get_edl())
570 EDL *edl = vwindow->get_edl();
571 vwindow->gui->unlock_window();
572 vwindow->playback_engine->interrupt_playback(1);
573 vwindow->gui->lock_window("VWindowEditing::prev_label");
575 Label *current = edl->labels->prev_label(
576 edl->local_session->get_selectionstart(1));
581 edl->local_session->set_selectionstart(0);
582 edl->local_session->set_selectionend(0);
583 vwindow->update_position(CHANGE_NONE, 0, 1, 0);
584 vwindow->gui->timebar->update(1);
588 edl->local_session->set_selectionstart(current->position);
589 edl->local_session->set_selectionend(current->position);
590 vwindow->update_position(CHANGE_NONE, 0, 1, 0);
591 vwindow->gui->timebar->update(1);
596 void VWindowEditing::next_label()
598 if(vwindow->get_edl())
600 EDL *edl = vwindow->get_edl();
601 Label *current = edl->labels->next_label(
602 edl->local_session->get_selectionstart(1));
605 vwindow->gui->unlock_window();
606 vwindow->playback_engine->interrupt_playback(1);
607 vwindow->gui->lock_window("VWindowEditing::next_label 1");
609 double position = edl->tracks->total_length();
610 edl->local_session->set_selectionstart(position);
611 edl->local_session->set_selectionend(position);
612 vwindow->update_position(CHANGE_NONE, 0, 1, 0);
613 vwindow->gui->timebar->update(1);
617 vwindow->gui->unlock_window();
618 vwindow->playback_engine->interrupt_playback(1);
619 vwindow->gui->lock_window("VWindowEditing::next_label 2");
621 edl->local_session->set_selectionstart(current->position);
622 edl->local_session->set_selectionend(current->position);
623 vwindow->update_position(CHANGE_NONE, 0, 1, 0);
624 vwindow->gui->timebar->update(1);
629 void VWindowEditing::set_inpoint()
631 vwindow->set_inpoint();
634 void VWindowEditing::set_outpoint()
636 vwindow->set_outpoint();
639 void VWindowEditing::clear_inpoint()
641 vwindow->clear_inpoint();
644 void VWindowEditing::clear_outpoint()
646 vwindow->clear_outpoint();
649 void VWindowEditing::to_clip()
651 if(vwindow->get_edl())
654 EDL *edl = vwindow->get_edl();
655 double start = edl->local_session->get_selectionstart();
656 double end = edl->local_session->get_selectionend();
658 if(EQUIV(start, end))
660 end = edl->tracks->total_length();
678 EDL *new_edl = new EDL(mwindow->edl);
679 new_edl->create_objects();
680 new_edl->load_xml(&file, LOAD_ALL);
681 sprintf(new_edl->local_session->clip_title, _("Clip %d"), mwindow->session->clip_number++);
682 new_edl->local_session->set_selectionstart(0);
683 new_edl->local_session->set_selectionend(0);
686 //printf("VWindowEditing::to_clip 1 %s\n", edl->local_session->clip_title);
688 vwindow->clip_edit->create_clip(new_edl);
698 VWindowSource::VWindowSource(MWindow *mwindow, VWindowGUI *vwindow, int x, int y)
699 : BC_PopupTextBox(vwindow,
707 this->mwindow = mwindow;
708 this->vwindow = vwindow;
711 VWindowSource::~VWindowSource()
715 int VWindowSource::handle_event()
726 VWindowTransport::VWindowTransport(MWindow *mwindow,
730 : PlayTransport(mwindow,
738 EDL* VWindowTransport::get_edl()
740 return gui->vwindow->get_edl();
744 void VWindowTransport::goto_start()
746 gui->unlock_window();
747 handle_transport(REWIND, 1);
748 gui->lock_window("VWindowTransport::goto_start");
749 gui->vwindow->goto_start();
752 void VWindowTransport::goto_end()
754 gui->unlock_window();
755 handle_transport(GOTO_END, 1);
756 gui->lock_window("VWindowTransport::goto_end");
757 gui->vwindow->goto_end();
763 VWindowCanvas::VWindowCanvas(MWindow *mwindow, VWindowGUI *gui)
766 mwindow->theme->vcanvas_x,
767 mwindow->theme->vcanvas_y,
768 mwindow->theme->vcanvas_w,
769 mwindow->theme->vcanvas_h,
772 //printf("VWindowCanvas::VWindowCanvas %d %d\n", __LINE__, mwindow->theme->vcanvas_x);
773 this->mwindow = mwindow;
777 void VWindowCanvas::zoom_resize_window(float percentage)
779 EDL *edl = gui->vwindow->get_edl();
780 if(!edl) edl = mwindow->edl;
782 int canvas_w, canvas_h;
785 // Get required canvas size
786 calculate_sizes(edl->get_aspect_ratio(),
787 edl->session->output_w,
788 edl->session->output_h,
793 // Estimate window size from current borders
794 new_w = canvas_w + (gui->get_w() - mwindow->theme->vcanvas_w);
795 new_h = canvas_h + (gui->get_h() - mwindow->theme->vcanvas_h);
797 mwindow->session->vwindow_w = new_w;
798 mwindow->session->vwindow_h = new_h;
800 mwindow->theme->get_vwindow_sizes(gui);
802 // Estimate again from new borders
803 new_w = canvas_w + (mwindow->session->vwindow_w - mwindow->theme->vcanvas_w);
804 new_h = canvas_h + (mwindow->session->vwindow_h - mwindow->theme->vcanvas_h);
807 gui->resize_window(new_w, new_h);
808 gui->resize_event(new_w, new_h);
811 void VWindowCanvas::close_source()
813 gui->vwindow->delete_source(1, 1);
817 void VWindowCanvas::draw_refresh(int flush)
819 EDL *edl = gui->vwindow->get_edl();
821 if(!get_canvas()->get_video_on()) get_canvas()->clear_box(0, 0, get_canvas()->get_w(), get_canvas()->get_h());
822 if(!get_canvas()->get_video_on() && refresh_frame && edl)
824 float in_x1, in_y1, in_x2, in_y2;
825 float out_x1, out_y1, out_x2, out_y2;
835 get_canvas()->draw_vframe(refresh_frame,
838 (int)(out_x2 - out_x1),
839 (int)(out_y2 - out_y1),
842 (int)(in_x2 - in_x1),
843 (int)(in_y2 - in_y1),
847 if(!get_canvas()->get_video_on())
850 get_canvas()->flash(flush);
854 void VWindowCanvas::draw_overlays()
856 if(mwindow->session->vcanvas_highlighted)
858 get_canvas()->set_color(WHITE);
859 get_canvas()->set_inverse();
860 get_canvas()->draw_rectangle(0, 0, get_canvas()->get_w(), get_canvas()->get_h());
861 get_canvas()->draw_rectangle(1, 1, get_canvas()->get_w() - 2, get_canvas()->get_h() - 2);
862 get_canvas()->set_opaque();
866 int VWindowCanvas::get_fullscreen()
868 return mwindow->session->vwindow_fullscreen;
871 void VWindowCanvas::set_fullscreen(int value)
873 mwindow->session->vwindow_fullscreen = value;
913 void VWindowGUI::update_points()
915 EDL *edl = vwindow->get_edl();
917 //printf("VWindowGUI::update_points 1\n");
920 //printf("VWindowGUI::update_points 2\n");
921 long pixel = (long)((double)edl->local_session->in_point /
922 edl->tracks->total_playable_length() *
923 (mwindow->theme->vtimebar_w -
925 mwindow->theme->in_point[0]->get_w())) +
926 mwindow->theme->in_point[0]->get_w();
928 //printf("VWindowGUI::update_points 3 %d\n", edl->local_session->in_point);
931 //printf("VWindowGUI::update_points 3.1\n");
932 if(edl->local_session->in_point >= 0)
934 //printf("VWindowGUI::update_points 4\n");
935 if(edl->local_session->in_point != in_point->position ||
936 in_point->pixel != pixel)
938 in_point->pixel = pixel;
939 in_point->reposition();
942 //printf("VWindowGUI::update_points 5\n");
943 in_point->position = edl->local_session->in_point;
945 //printf("VWindowGUI::update_points 6\n");
946 if(edl->equivalent(in_point->position, edl->local_session->get_selectionstart(1)) ||
947 edl->equivalent(in_point->position, edl->local_session->get_selectionend(1)))
951 //printf("VWindowGUI::update_points 7\n");
960 if(edl->local_session->in_point >= 0)
962 //printf("VWindowGUI::update_points 8 %p\n", mwindow->theme->in_point);
963 add_subwindow(in_point =
964 new VWindowInPoint(mwindow,
968 edl->local_session->in_point));
969 //printf("VWindowGUI::update_points 9\n");
971 //printf("VWindowGUI::update_points 10\n");
973 pixel = (long)((double)edl->local_session->out_point /
974 (edl->tracks->total_playable_length() + 0.5) *
975 (mwindow->theme->vtimebar_w -
977 mwindow->theme->in_point[0]->get_w())) +
978 mwindow->theme->in_point[0]->get_w() *
983 if(edl->local_session->out_point >= 0 && pixel >= 0 && pixel <= mwindow->theme->vtimebar_w)
985 if(edl->local_session->out_point != out_point->position ||
986 out_point->pixel != pixel)
988 out_point->pixel = pixel;
989 out_point->reposition();
991 out_point->position = edl->local_session->out_point;
993 if(edl->equivalent(out_point->position, edl->local_session->get_selectionstart(1)) ||
994 edl->equivalent(out_point->position, edl->local_session->get_selectionend(1)))
995 out_point->update(1);
997 out_point->update(0);
1006 if(edl->local_session->out_point >= 0 && pixel >= 0 && pixel <= mwindow->theme->vtimebar_w)
1008 add_subwindow(out_point =
1009 new VWindowOutPoint(mwindow,
1013 edl->local_session->out_point));
1018 void VWindowGUI::update_labels()
1020 EDL *edl = vwindow->get_edl();
1023 for(Label *current = edl->labels->first;
1027 long pixel = (long)((current->position - edl->local_session->view_start) / edl->local_session->zoom_sample);
1029 if(pixel >= 0 && pixel < mwindow->theme->vtimebar_w)
1032 if(output >= labels.total)
1034 LabelGUI *new_label;
1035 add_subwindow(new_label = new LabelGUI(mwindow, this, pixel, 0, current->position));
1036 labels.append(new_label);
1039 // Reposition old label
1040 if(labels.values[output]->pixel != pixel)
1042 labels.values[output]->pixel = pixel;
1043 labels.values[output]->position = current->position;
1044 labels.values[output]->reposition();
1047 if(mwindow->edl->local_session->get_selectionstart(1) <= current->position &&
1048 mwindow->edl->local_session->get_selectionend(1) >= current->position)
1049 labels.values[output]->update(1);
1051 if(labels.values[output]->get_value())
1052 labels.values[output]->update(0);
1057 // Delete excess labels
1058 while(labels.total > output)
1060 labels.remove_object();
1066 VWindowInPoint::VWindowInPoint(MWindow *mwindow,
1071 : InPointGUI(mwindow,
1079 int VWindowInPoint::handle_event()
1081 EDL *edl = gui->vwindow->get_edl();
1085 double position = edl->align_to_frame(this->position, 0);
1087 edl->local_session->set_selectionstart(position);
1088 edl->local_session->set_selectionend(position);
1089 gui->timebar->update(1);
1092 mwindow->vwindow->update_position(CHANGE_NONE, 0, 1, 0);
1099 VWindowOutPoint::VWindowOutPoint(MWindow *mwindow,
1104 : OutPointGUI(mwindow,
1112 int VWindowOutPoint::handle_event()
1114 EDL *edl = gui->vwindow->get_edl();
1118 double position = edl->align_to_frame(this->position, 0);
1120 edl->local_session->set_selectionstart(position);
1121 edl->local_session->set_selectionend(position);
1122 gui->timebar->update(1);
1125 mwindow->vwindow->update_position(CHANGE_NONE, 0, 1, 0);