2 Copyright (C) 2000-2003 Paul Davis
3 Written by Colin Law, CMT, Glasgow
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "imageframe_view.h"
23 #include "imageframe_time_axis.h"
24 #include "imageframe_time_axis_view.h"
25 #include "imageframe_time_axis_group.h"
26 #include "marker_time_axis_view.h"
27 #include "marker_time_axis.h"
28 #include "marker_view.h"
31 #include "canvas_impl.h"
33 #include <gtkmm2ext/gtk_ui.h>
34 #include <pbd/error.h>
36 #include <sys/types.h>
37 #include <sys/socket.h>
38 #include <netinet/in.h>
40 #include <arpa/inet.h>
42 #include "imageframe_socket_handler.h"
43 #include "ardour_image_compositor_socket.h"
44 #include "public_editor.h"
48 /* <CMT Additions file="editor.cc"> */
51 Editor::add_imageframe_time_axis(const string & track_name, void* src)
53 // check for duplicate name
54 if(get_named_time_axis(track_name))
56 warning << "Repeated time axis name" << std::endl ;
60 Gtkmm2ext::UI::instance()->call_slot(bind(mem_fun(*this, &Editor::handle_new_imageframe_time_axis_view),track_name, src)) ;
65 Editor::connect_to_image_compositor()
67 if(image_socket_listener == 0)
69 image_socket_listener = ImageFrameSocketHandler::create_instance(*this) ;
72 if(image_socket_listener->is_connected() == true)
77 // XXX should really put this somewhere safe
78 std::string host_ip = "127.0.0.1" ;
80 bool retcode = image_socket_listener->connect(host_ip,ardourvis::DEFAULT_PORT) ;
84 // XXX need to get some return status here
85 warning << "Image Compositor Connection attempt failed" << std::endl ;
89 // add the socket to the gui loop, and keep the retuned tag value of the input
90 gint tag = gdk_input_add(image_socket_listener->get_socket_descriptor(), GDK_INPUT_READ,ImageFrameSocketHandler::image_socket_callback,image_socket_listener) ;
91 image_socket_listener->set_gdk_input_tag(tag) ;
95 Editor::scroll_timeaxis_to_imageframe_item(const TimeAxisViewItem* item)
98 //jack_nframes_t offset = static_cast<jack_nframes_t>(frames_per_unit * (edit_hscroll_slider_width/2)) ;
99 jack_nframes_t offset = 0;
101 jack_nframes_t x_pos = 0 ;
102 if(item->get_position() < offset)
108 x_pos = item->get_position() - offset + (item->get_duration() / 2) ;
111 reposition_x_origin(x_pos) ;
115 Editor::add_imageframe_marker_time_axis(const string & track_name, TimeAxisView* marked_track, void* src)
117 // Can we only bind 2 data Items?
118 // @todo we really want to bind the src attribute too, for the moment tracks can only be added remotely,
119 // so this is not too much of an issue, however will need to be looked at again
120 Gtkmm2ext::UI::instance()->call_slot(sigc::bind(mem_fun(*this, &Editor::handle_new_imageframe_marker_time_axis_view),track_name, marked_track)) ;
124 Editor::popup_imageframe_edit_menu(int button, int32_t time, ArdourCanvas::Item* ifv, bool with_item)
126 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(clicked_trackview) ;
130 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_selected_imageframe_group() ;
134 ImageFrameView* selected_ifv = ifta->get_view()->get_selected_imageframe_view() ;
135 ifta->popup_imageframe_edit_menu(button, time, selected_ifv, with_item) ;
141 Editor::popup_marker_time_axis_edit_menu(int button, int32_t time, ArdourCanvas::Item* ifv, bool with_item)
143 MarkerTimeAxis* mta = dynamic_cast<MarkerTimeAxis*>(clicked_trackview) ;
147 MarkerView* selected_mv = mta->get_view()->get_selected_time_axis_item() ;
150 mta->popup_marker_time_axis_edit_menu(button,time, selected_mv, with_item) ;
156 Editor::get_named_time_axis(const string & name)
158 TimeAxisView* tav = 0 ;
160 for (TrackViewList::const_iterator i = track_views.begin(); i != track_views.end(); ++i)
162 if (((TimeAxisView*)*i)->name() == name)
164 tav = ((TimeAxisView*)*i) ;
171 /* </CMT Additions file="editor.cc"> */
178 /* <CMT Additions file="editor_canvas_events.cc"> */
180 Editor::canvas_imageframe_item_view_event (GdkEvent *event, ArdourCanvas::Item* item, ImageFrameView *ifv)
183 ImageFrameTimeAxisGroup* iftag = 0 ;
187 case GDK_BUTTON_PRESS:
188 case GDK_2BUTTON_PRESS:
189 case GDK_3BUTTON_PRESS:
190 clicked_trackview = &ifv->get_time_axis_view();
191 iftag = ifv->get_time_axis_group() ;
192 dynamic_cast<ImageFrameTimeAxis*>(clicked_trackview)->get_view()->set_selected_imageframe_view(iftag, ifv);
193 ret = button_press_handler (item, event, ImageFrameItem) ;
195 case GDK_BUTTON_RELEASE:
196 ret = button_release_handler (item, event, ImageFrameItem) ;
198 case GDK_MOTION_NOTIFY:
199 ret = motion_handler (item, event, ImageFrameItem) ;
208 Editor::canvas_imageframe_start_handle_event (GdkEvent *event, ArdourCanvas::Item* item, ImageFrameView *ifv)
211 ImageFrameTimeAxisGroup* iftag = 0 ;
215 case GDK_BUTTON_PRESS:
216 case GDK_2BUTTON_PRESS:
217 case GDK_3BUTTON_PRESS:
218 clicked_trackview = &ifv->get_time_axis_view() ;
219 iftag = ifv->get_time_axis_group() ;
220 dynamic_cast<ImageFrameTimeAxis*>(clicked_trackview)->get_view()->set_selected_imageframe_view(iftag, ifv);
222 ret = button_press_handler (item, event, ImageFrameHandleStartItem) ;
224 case GDK_BUTTON_RELEASE:
225 ret = button_release_handler (item, event, ImageFrameHandleStartItem) ;
227 case GDK_MOTION_NOTIFY:
228 ret = motion_handler (item, event, ImageFrameHandleStartItem) ;
230 case GDK_ENTER_NOTIFY:
231 ret = enter_handler (item, event, ImageFrameHandleStartItem) ;
233 case GDK_LEAVE_NOTIFY:
234 ret = leave_handler (item, event, ImageFrameHandleStartItem) ;
243 Editor::canvas_imageframe_end_handle_event (GdkEvent *event, ArdourCanvas::Item* item, ImageFrameView *ifv)
246 ImageFrameTimeAxisGroup* iftag = 0 ;
250 case GDK_BUTTON_PRESS:
251 case GDK_2BUTTON_PRESS:
252 case GDK_3BUTTON_PRESS:
253 clicked_trackview = &ifv->get_time_axis_view() ;
254 iftag = ifv->get_time_axis_group() ;
255 dynamic_cast<ImageFrameTimeAxis*>(clicked_trackview)->get_view()->set_selected_imageframe_view(iftag, ifv);
257 ret = button_press_handler (item, event, ImageFrameHandleEndItem) ;
259 case GDK_BUTTON_RELEASE:
260 ret = button_release_handler (item, event, ImageFrameHandleEndItem) ;
262 case GDK_MOTION_NOTIFY:
263 ret = motion_handler (item, event, ImageFrameHandleEndItem) ;
265 case GDK_ENTER_NOTIFY:
266 ret = enter_handler (item, event, ImageFrameHandleEndItem) ;
268 case GDK_LEAVE_NOTIFY:
269 ret = leave_handler (item, event, ImageFrameHandleEndItem);
278 Editor::canvas_imageframe_view_event (GdkEvent* event, ArdourCanvas::Item* item, ImageFrameTimeAxis* ifta)
283 case GDK_BUTTON_PRESS:
284 case GDK_2BUTTON_PRESS:
285 case GDK_3BUTTON_PRESS:
286 clicked_trackview = ifta ;
287 ret = button_press_handler (item, event, ImageFrameTimeAxisItem) ;
289 case GDK_BUTTON_RELEASE:
290 ret = button_release_handler (item, event, ImageFrameTimeAxisItem) ;
292 case GDK_MOTION_NOTIFY:
301 Editor::canvas_marker_time_axis_view_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerTimeAxis* mta)
306 case GDK_BUTTON_PRESS:
307 case GDK_2BUTTON_PRESS:
308 case GDK_3BUTTON_PRESS:
309 clicked_trackview = mta ;
310 ret = button_press_handler(item, event, MarkerTimeAxisItem) ;
312 case GDK_BUTTON_RELEASE:
313 ret = button_release_handler(item, event, MarkerTimeAxisItem) ;
315 case GDK_MOTION_NOTIFY:
324 Editor::canvas_markerview_item_view_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerView* mta)
329 case GDK_BUTTON_PRESS:
330 case GDK_2BUTTON_PRESS:
331 case GDK_3BUTTON_PRESS:
332 clicked_trackview = &mta->get_time_axis_view() ;
333 dynamic_cast<MarkerTimeAxis*>(clicked_trackview)->get_view()->set_selected_time_axis_item(mta);
334 ret = button_press_handler(item, event, MarkerViewItem) ;
336 case GDK_BUTTON_RELEASE:
337 ret = button_release_handler(item, event, MarkerViewItem) ;
339 case GDK_MOTION_NOTIFY:
340 ret = motion_handler(item, event, MarkerViewItem) ;
349 Editor::canvas_markerview_start_handle_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerView* mta)
354 case GDK_BUTTON_PRESS:
355 case GDK_2BUTTON_PRESS:
356 case GDK_3BUTTON_PRESS:
357 clicked_trackview = &mta->get_time_axis_view() ;
358 dynamic_cast<MarkerTimeAxis*>(clicked_trackview)->get_view()->set_selected_time_axis_item(mta) ;
359 ret = button_press_handler(item, event, MarkerViewHandleStartItem) ;
361 case GDK_BUTTON_RELEASE:
362 ret = button_release_handler(item, event, MarkerViewHandleStartItem) ;
364 case GDK_MOTION_NOTIFY:
365 ret = motion_handler(item, event, MarkerViewHandleStartItem) ;
367 case GDK_ENTER_NOTIFY:
368 ret = enter_handler(item, event, MarkerViewHandleStartItem) ;
370 case GDK_LEAVE_NOTIFY:
371 ret = leave_handler(item, event, MarkerViewHandleStartItem) ;
380 Editor::canvas_markerview_end_handle_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerView* mta)
385 case GDK_BUTTON_PRESS:
386 case GDK_2BUTTON_PRESS:
387 case GDK_3BUTTON_PRESS:
388 clicked_trackview = &mta->get_time_axis_view() ;
389 dynamic_cast<MarkerTimeAxis*>(clicked_trackview)->get_view()->set_selected_time_axis_item(mta) ;
390 ret = button_press_handler(item, event, MarkerViewHandleEndItem) ;
392 case GDK_BUTTON_RELEASE:
393 ret = button_release_handler(item, event, MarkerViewHandleEndItem) ;
395 case GDK_MOTION_NOTIFY:
396 ret = motion_handler(item, event, MarkerViewHandleEndItem) ;
398 case GDK_ENTER_NOTIFY:
399 ret = enter_handler(item, event, MarkerViewHandleEndItem) ;
401 case GDK_LEAVE_NOTIFY:
402 ret = leave_handler(item, event, MarkerViewHandleEndItem) ;
411 /* </CMT Additions file="editor_canvas_events.cc"> */
415 ---------------------------------------------------------------------------------------------------
416 ---------------------------------------------------------------------------------------------------
417 ---------------------------------------------------------------------------------------------------
422 /* <CMT Additions file="editor_mouse.cc"> */
425 Editor::start_imageframe_grab(ArdourCanvas::Item* item, GdkEvent* event)
427 ImageFrameView* ifv = ((ImageFrameTimeAxis*)clicked_trackview)->get_view()->get_selected_imageframe_view() ;
428 drag_info.copy = false ;
429 drag_info.item = item ;
430 drag_info.data = ifv ;
431 drag_info.motion_callback = &Editor::imageframe_drag_motion_callback;
432 drag_info.finished_callback = &Editor::timeaxis_item_drag_finished_callback;
433 drag_info.last_frame_position = ifv->get_position() ;
435 drag_info.last_trackview = &ifv->get_time_axis_view() ;
437 /* this is subtle. raising the regionview itself won't help,
438 because raise_to_top() just puts the item on the top of
439 its parent's stack. so, we need to put the trackview canvas_display group
440 on the top, since its parent is the whole canvas.
442 however, this hides the measure bars within that particular trackview,
443 so move them to the top afterwards.
446 drag_info.item->raise_to_top();
447 drag_info.last_trackview->canvas_display->raise_to_top();
448 //time_line_group->raise_to_top();
449 cursor_group->raise_to_top ();
453 drag_info.pointer_frame_offset = pixel_to_frame(drag_info.grab_x) - drag_info.last_frame_position;
458 Editor::start_markerview_grab(ArdourCanvas::Item* item, GdkEvent* event)
460 MarkerView* mv = ((MarkerTimeAxis*)clicked_trackview)->get_view()->get_selected_time_axis_item() ;
461 drag_info.copy = false ;
462 drag_info.item = item ;
463 drag_info.data = mv ;
464 drag_info.motion_callback = &Editor::markerview_drag_motion_callback;
465 drag_info.finished_callback = &Editor::timeaxis_item_drag_finished_callback;
466 drag_info.last_frame_position = mv->get_position() ;
468 drag_info.last_trackview = &mv->get_time_axis_view() ;
470 /* this is subtle. raising the regionview itself won't help,
471 because raise_to_top() just puts the item on the top of
472 its parent's stack. so, we need to put the trackview canvas_display group
473 on the top, since its parent is the whole canvas.
475 however, this hides the measure bars within that particular trackview,
476 so move them to the top afterwards.
479 drag_info.item->raise_to_top();
480 drag_info.last_trackview->canvas_display->raise_to_top();
481 //time_line_group->raise_to_top();
482 cursor_group->raise_to_top ();
486 drag_info.pointer_frame_offset = pixel_to_frame(drag_info.grab_x) - drag_info.last_frame_position ;
491 Editor::markerview_drag_motion_callback(ArdourCanvas::Item*, GdkEvent* event)
495 MarkerView* mv = reinterpret_cast<MarkerView*>(drag_info.data) ;
496 jack_nframes_t pending_region_position ;
497 jack_nframes_t pointer_frame ;
499 pointer_frame = event_frame(event, &cx, &cy) ;
501 snap_to(pointer_frame) ;
503 if (pointer_frame > (jack_nframes_t) drag_info.pointer_frame_offset)
505 pending_region_position = pointer_frame - drag_info.pointer_frame_offset ;
506 snap_to(pending_region_position) ;
508 // we dont allow marker items to extend beyond, or in front of the marked items so
509 // cap the value to the marked items position and duration
510 if((pending_region_position + mv->get_duration()) >= ((mv->get_marked_item()->get_position()) + (mv->get_marked_item()->get_duration())))
512 pending_region_position = (mv->get_marked_item()->get_position() + mv->get_marked_item()->get_duration()) - (mv->get_duration()) ;
514 else if(pending_region_position <= mv->get_marked_item()->get_position())
516 pending_region_position = mv->get_marked_item()->get_position() ;
521 pending_region_position = mv->get_marked_item()->get_position() ;
524 drag_info.last_frame_position = pending_region_position ;
526 // we treat this as a special case, usually we want to send the identitiy of the caller
527 // but in this case, that would trigger our socket handler to handle the event, sending
528 // notification to the image compositor. This would be fine, except that we have not
529 // finished the drag, we therefore do not want to sent notification until we have
530 // completed the drag, only then do we want the image compositor notofied.
531 // We therefore set the caller identity to the special case of 0
532 mv->set_position(pending_region_position, 0) ;
534 show_verbose_time_cursor(pending_region_position) ;
538 Editor::imageframe_drag_motion_callback(ArdourCanvas::Item*, GdkEvent* event)
542 ImageFrameView* ifv = reinterpret_cast<ImageFrameView*>(drag_info.data) ;
544 jack_nframes_t pending_region_position;
545 jack_nframes_t pointer_frame;
547 pointer_frame = event_frame(event, &cx, &cy) ;
549 snap_to(pointer_frame) ;
551 if (pointer_frame > (jack_nframes_t) drag_info.pointer_frame_offset)
553 pending_region_position = pointer_frame - drag_info.pointer_frame_offset ;
554 snap_to(pending_region_position) ;
558 pending_region_position = 0 ;
561 drag_info.grab_x = cx;
562 //drag_info.last_frame_position = pending_region_position ;
563 drag_info.current_pointer_frame = pending_region_position ;
565 // we treat this as a special case, usually we want to send the identitiy of the caller
566 // but in this case, that would trigger our socket handler to handle the event, sending
567 // notification to the image compositor. This would be fine, except that we have not
568 // finished the drag, we therefore do not want to sent notification until we have
569 // completed the drag, only then do we want the image compositor notofied.
570 // We therefore set the caller identity to the special case of 0
571 ifv->set_position(pending_region_position, 0) ;
573 show_verbose_time_cursor(pending_region_position) ;
577 Editor::timeaxis_item_drag_finished_callback(ArdourCanvas::Item*, GdkEvent* event)
579 jack_nframes_t where ;
580 TimeAxisViewItem* tavi = reinterpret_cast<TimeAxisViewItem*>(drag_info.data) ;
582 bool item_x_movement = (drag_info.last_frame_position != tavi->get_position()) ;
584 hide_verbose_canvas_cursor() ;
586 /* no x or y movement either means the regionview hasn't been moved, or has been moved
587 but is back in it's original position/trackview.*/
589 if(!item_x_movement && event && event->type == GDK_BUTTON_RELEASE)
591 /* No motion: either set the current region, or align the clicked region
592 with the current one.
599 /* base the new region position on the current position of the regionview.*/
600 where = drag_info.current_pointer_frame ;
602 // final call to set position after the motion to tell interested parties of the new position
603 tavi->set_position(where, this) ;
607 //where = tavi->get_position() ;
615 Editor::imageframe_start_handle_op(ArdourCanvas::Item* item, GdkEvent* event)
617 // get the selected item from the parent time axis
618 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(clicked_trackview) ;
621 ImageFrameView* ifv = ifta->get_view()->get_selected_imageframe_view() ;
624 fatal << _("programming error: no ImageFrameView selected") << endmsg;
629 drag_info.item = ifv->get_canvas_frame() ;
630 drag_info.data = ifv;
631 drag_info.grab_x = event->motion.x;
632 drag_info.cumulative_x_drag = 0;
633 drag_info.motion_callback = &Editor::imageframe_start_handle_trim_motion ;
634 drag_info.finished_callback = &Editor::imageframe_start_handle_end_trim ;
636 flush_track_canvas() ;
640 show_verbose_time_cursor(ifv->get_position(), 10) ;
645 Editor::imageframe_end_handle_op(ArdourCanvas::Item* item, GdkEvent* event)
647 // get the selected item from the parent time axis
648 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(clicked_trackview) ;
652 ImageFrameView* ifv = ifta->get_view()->get_selected_imageframe_view() ;
656 fatal << _("programming error: no ImageFrameView selected") << endmsg ;
661 drag_info.item = ifv->get_canvas_frame() ;
662 drag_info.data = ifv ;
663 drag_info.grab_x = event->motion.x ;
664 drag_info.cumulative_x_drag = 0 ;
665 drag_info.motion_callback = &Editor::imageframe_end_handle_trim_motion ;
666 drag_info.finished_callback = &Editor::imageframe_end_handle_end_trim ;
668 flush_track_canvas() ;
670 start_grab(event, trimmer_cursor) ;
672 show_verbose_time_cursor(ifv->get_position() + ifv->get_duration(), 10) ;
677 Editor::imageframe_start_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* event)
679 ImageFrameView* ifv = reinterpret_cast<ImageFrameView*> (drag_info.data) ;
681 jack_nframes_t start = 0 ;
682 jack_nframes_t end = 0 ;
683 jack_nframes_t pointer_frame = event_frame(event) ;
685 // chekc th eposition of the item is not locked
686 if(!ifv->get_position_locked()) {
687 snap_to(pointer_frame) ;
689 if(pointer_frame != drag_info.last_pointer_frame) {
690 start = ifv->get_position() ;
691 end = ifv->get_position() + ifv->get_duration() ;
693 if (pointer_frame > end) {
696 start = pointer_frame ;
699 // are we getting bigger or smaller?
700 jack_nframes_t new_dur_val = end - start ;
702 // start handle, so a smaller pointer frame increases our component size
703 if(pointer_frame <= drag_info.grab_frame)
705 if(ifv->get_max_duration_active() && (new_dur_val > ifv->get_max_duration()))
707 new_dur_val = ifv->get_max_duration() ;
708 start = end - new_dur_val ;
712 // current values are ok
717 if(ifv->get_min_duration_active() && (new_dur_val < ifv->get_min_duration()))
719 new_dur_val = ifv->get_min_duration() ;
720 start = end - new_dur_val ;
724 // current values are ok
728 drag_info.last_pointer_frame = pointer_frame ;
730 /* re-calculatethe duration and position of the imageframeview */
731 drag_info.cumulative_x_drag = new_dur_val ;
733 // we treat this as a special case, usually we want to send the identitiy of the caller
734 // but in this case, that would trigger our socket handler to handle the event, sending
735 // notification to the image compositor. This would be fine, except that we have not
736 // finished the drag, we therefore do not want to sent notification until we have
737 // completed the drag, only then do we want the image compositor notofied.
738 // We therefore set the caller identity to the special case of 0
739 ifv->set_duration(new_dur_val, 0) ;
740 ifv->set_position(start, 0) ;
744 show_verbose_time_cursor(start, 10) ;
748 Editor::imageframe_start_handle_end_trim(ArdourCanvas::Item* item, GdkEvent* event)
750 ImageFrameView* ifv = reinterpret_cast<ImageFrameView *> (drag_info.data) ;
752 if (drag_info.cumulative_x_drag == 0)
758 jack_nframes_t temp = ifv->get_position() + ifv->get_duration() ;
760 ifv->set_position((jack_nframes_t) (temp - drag_info.cumulative_x_drag), this) ;
761 ifv->set_duration((jack_nframes_t) drag_info.cumulative_x_drag, this) ;
764 flush_track_canvas() ;
768 Editor::imageframe_end_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* event)
770 ImageFrameView* ifv = reinterpret_cast<ImageFrameView *> (drag_info.data) ;
772 jack_nframes_t start = 0 ;
773 jack_nframes_t end = 0 ;
774 jack_nframes_t pointer_frame = event_frame(event) ;
775 jack_nframes_t new_dur_val = 0 ;
777 snap_to(pointer_frame) ;
779 if (pointer_frame != drag_info.last_pointer_frame)
781 start = ifv->get_position() ;
782 end = ifv->get_position() + ifv->get_duration() ;
783 if (pointer_frame < start)
789 end = pointer_frame ;
792 new_dur_val = end - start ;
794 // are we getting bigger or smaller?
795 if(pointer_frame >= drag_info.last_pointer_frame)
797 if(ifv->get_max_duration_active() && (new_dur_val > ifv->get_max_duration()))
799 new_dur_val = ifv->get_max_duration() ;
804 if(ifv->get_min_duration_active() && (new_dur_val < ifv->get_min_duration()))
806 new_dur_val = ifv->get_min_duration() ;
810 drag_info.last_pointer_frame = pointer_frame ;
811 drag_info.cumulative_x_drag = new_dur_val ;
813 // we treat this as a special case, usually we want to send the identitiy of the caller
814 // but in this case, that would trigger our socket handler to handle the event, sending
815 // notification to the image compositor. This would be fine, except that we have not
816 // finished the drag, we therefore do not want to sent notification until we have
817 // completed the drag, only then do we want the image compositor notofied.
818 // We therefore set the caller identity to the special case of 0
819 ifv->set_duration(new_dur_val, 0) ;
822 show_verbose_time_cursor(new_dur_val, 10) ;
827 Editor::imageframe_end_handle_end_trim (ArdourCanvas::Item* item, GdkEvent* event)
829 ImageFrameView* ifv = reinterpret_cast<ImageFrameView *> (drag_info.data) ;
831 if (drag_info.cumulative_x_drag == 0)
837 jack_nframes_t new_duration = (jack_nframes_t)drag_info.cumulative_x_drag ;
838 if((new_duration <= ifv->get_max_duration()) && (new_duration >= ifv->get_min_duration()))
840 ifv->set_duration(new_duration, this) ;
844 flush_track_canvas ();
849 Editor::markerview_item_start_handle_op(ArdourCanvas::Item* item, GdkEvent* event)
851 MarkerView* mv = reinterpret_cast<MarkerTimeAxis*>(clicked_trackview)->get_view()->get_selected_time_axis_item() ;
855 fatal << _("programming error: no MarkerView selected") << endmsg ;
860 drag_info.item = mv->get_canvas_frame() ;
862 drag_info.grab_x = event->motion.x;
864 drag_info.cumulative_x_drag = 0 ;
865 drag_info.motion_callback = &Editor::markerview_start_handle_trim_motion ;
866 drag_info.finished_callback = &Editor::markerview_start_handle_end_trim ;
868 flush_track_canvas() ;
870 start_grab(event, trimmer_cursor) ;
874 Editor::markerview_item_end_handle_op(ArdourCanvas::Item* item, GdkEvent* event)
876 MarkerView* mv = reinterpret_cast<MarkerTimeAxis*>(clicked_trackview)->get_view()->get_selected_time_axis_item() ;
879 fatal << _("programming error: no MarkerView selected") << endmsg ;
884 drag_info.item = mv->get_canvas_frame() ;
885 drag_info.data = mv ;
886 drag_info.grab_x = event->motion.x ;
887 drag_info.cumulative_x_drag = 0 ;
889 drag_info.motion_callback = &Editor::markerview_end_handle_trim_motion ;
890 drag_info.finished_callback = &Editor::markerview_end_handle_end_trim ;
892 flush_track_canvas () ;
894 start_grab(event, trimmer_cursor) ;
899 Editor::markerview_start_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* event)
901 MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
903 jack_nframes_t start = 0 ;
904 jack_nframes_t end = 0 ;
905 jack_nframes_t pointer_frame = event_frame(event) ;
907 // chekc th eposition of the item is not locked
908 if(!mv->get_position_locked())
910 snap_to(pointer_frame) ;
911 if(pointer_frame != drag_info.last_pointer_frame)
913 start = mv->get_position() ;
914 end = mv->get_position() + mv->get_duration() ;
916 if (pointer_frame > end)
922 start = pointer_frame ;
925 // are we getting bigger or smaller?
926 jack_nframes_t new_dur_val = end - start ;
928 if(pointer_frame <= drag_info.grab_frame)
930 if(mv->get_max_duration_active() && (new_dur_val > mv->get_max_duration()))
932 new_dur_val = mv->get_max_duration() ;
933 start = end - new_dur_val ;
937 // current values are ok
942 if(mv->get_min_duration_active() && (new_dur_val < mv->get_min_duration()))
944 new_dur_val = mv->get_min_duration() ;
945 start = end - new_dur_val ;
949 // current values are ok
953 drag_info.last_pointer_frame = pointer_frame ;
955 /* re-calculatethe duration and position of the imageframeview */
956 drag_info.cumulative_x_drag = new_dur_val ;
958 // we treat this as a special case, usually we want to send the identitiy of the caller
959 // but in this case, that would trigger our socket handler to handle the event, sending
960 // notification to the image compositor. This would be fine, except that we have not
961 // finished the drag, we therefore do not want to sent notification until we have
962 // completed the drag, only then do we want the image compositor notofied.
963 // We therefore set the caller identity to the special case of 0
964 mv->set_duration(new_dur_val, 0) ;
965 mv->set_position(start, 0) ;
969 show_verbose_time_cursor(start, 10) ;
973 Editor::markerview_start_handle_end_trim(ArdourCanvas::Item* item, GdkEvent* event)
975 MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
977 if (drag_info.cumulative_x_drag == 0)
983 jack_nframes_t temp = mv->get_position() + mv->get_duration() ;
985 mv->set_position((jack_nframes_t) (temp - drag_info.cumulative_x_drag), this) ;
986 mv->set_duration((jack_nframes_t) drag_info.cumulative_x_drag, this) ;
989 flush_track_canvas() ;
993 Editor::markerview_end_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* event)
995 MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
997 jack_nframes_t start = 0 ;
998 jack_nframes_t end = 0 ;
999 jack_nframes_t pointer_frame = event_frame(event) ;
1000 jack_nframes_t new_dur_val = 0 ;
1002 snap_to(pointer_frame) ;
1004 if (pointer_frame != drag_info.last_pointer_frame)
1006 start = mv->get_position() ;
1007 end = mv->get_position() + mv->get_duration() ;
1009 if(pointer_frame < start)
1015 end = pointer_frame ;
1018 new_dur_val = end - start ;
1020 // are we getting bigger or smaller?
1021 if(pointer_frame >= drag_info.last_pointer_frame)
1023 // we cant extend beyond the item we are marking
1024 ImageFrameView* marked_item = mv->get_marked_item() ;
1025 jack_nframes_t marked_end = marked_item->get_position() + marked_item->get_duration() ;
1027 if(mv->get_max_duration_active() && (new_dur_val > mv->get_max_duration()))
1029 if((start + mv->get_max_duration()) > marked_end)
1031 new_dur_val = marked_end - start ;
1035 new_dur_val = mv->get_max_duration() ;
1038 else if(end > marked_end)
1040 new_dur_val = marked_end - start ;
1045 if(mv->get_min_duration_active() && (new_dur_val < mv->get_min_duration()))
1047 new_dur_val = mv->get_min_duration() ;
1052 drag_info.last_pointer_frame = pointer_frame ;
1053 drag_info.cumulative_x_drag = new_dur_val ;
1055 // we treat this as a special case, usually we want to send the identitiy of the caller
1056 // but in this case, that would trigger our socket handler to handle the event, sending
1057 // notification to the image compositor. This would be fine, except that we have not
1058 // finished the drag, we therefore do not want to sent notification until we have
1059 // completed the drag, only then do we want the image compositor notofied.
1060 // We therefore set the caller identity to the special case of 0
1061 mv->set_duration(new_dur_val, 0) ;
1064 show_verbose_time_cursor(new_dur_val, 10) ;
1069 Editor::markerview_end_handle_end_trim (ArdourCanvas::Item* item, GdkEvent* event)
1071 MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
1073 if (drag_info.cumulative_x_drag == 0)
1079 jack_nframes_t new_duration = (jack_nframes_t)drag_info.cumulative_x_drag ;
1080 mv->set_duration(new_duration, this) ;
1083 flush_track_canvas() ;
1087 /* </CMT Additions file="editor_mouse.cc"> */
1095 /* <CMT Additions file="editor_route_list.cc"> */
1098 Editor::handle_new_imageframe_time_axis_view(const string & track_name, void* src)
1100 ImageFrameTimeAxis* iftav ;
1101 iftav = new ImageFrameTimeAxis(track_name, *this, *session, track_canvas) ;
1102 iftav->set_time_axis_name(track_name, this) ;
1103 track_views.push_back(iftav) ;
1105 TreeModel::Row row = *(route_display_model->append());
1107 row[route_display_columns.text] = iftav->name();
1108 row[route_display_columns.tv] = iftav;
1109 route_list.get_selection()->select (row);
1111 iftav->GoingAway.connect(bind(mem_fun(*this, &Editor::remove_route), (TimeAxisView*)iftav)) ;
1112 iftav->gui_changed.connect(mem_fun(*this, &Editor::handle_gui_changes)) ;
1116 Editor::handle_new_imageframe_marker_time_axis_view(const string & track_name, TimeAxisView* marked_track)
1118 MarkerTimeAxis* mta = new MarkerTimeAxis (*this, *this->current_session(), track_canvas, track_name, marked_track) ;
1119 ((ImageFrameTimeAxis*)marked_track)->add_marker_time_axis(mta, this) ;
1120 track_views.push_back(mta) ;
1122 TreeModel::Row row = *(route_display_model->append());
1124 row[route_display_columns.text] = mta->name();
1125 row[route_display_columns.tv] = mta;
1126 route_list.get_selection()->select (row);
1128 mta->GoingAway.connect(bind(mem_fun(*this, &Editor::remove_route), (TimeAxisView*)mta)) ;
1132 /* </CMT Additions file="editor_route_list.cc"> */