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.
21 #include "imageframe_view.h"
22 #include "imageframe_time_axis.h"
23 #include "imageframe_time_axis_view.h"
24 #include "imageframe_time_axis_group.h"
25 #include "marker_time_axis_view.h"
26 #include "marker_time_axis.h"
27 #include "marker_view.h"
30 #include "canvas_impl.h"
32 #include <gtkmm2ext/gtk_ui.h>
33 #include <pbd/error.h>
35 #include <sys/types.h>
36 #include <sys/socket.h>
37 #include <netinet/in.h>
39 #include <arpa/inet.h>
41 #include "imageframe_socket_handler.h"
42 #include "ardour_image_compositor_socket.h"
43 #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 const char * 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 //nframes_t offset = static_cast<nframes_t>(frames_per_unit * (edit_hscroll_slider_width/2)) ;
101 nframes_t x_pos = 0 ;
103 if (item->get_position() < offset) {
106 x_pos = item->get_position() - offset + (item->get_duration() / 2);
109 reset_x_origin (x_pos);
113 Editor::add_imageframe_marker_time_axis(const string & track_name, TimeAxisView* marked_track, void* src)
115 // Can we only bind 2 data Items?
116 // @todo we really want to bind the src attribute too, for the moment tracks can only be added remotely,
117 // so this is not too much of an issue, however will need to be looked at again
118 Gtkmm2ext::UI::instance()->call_slot(sigc::bind(mem_fun(*this, &Editor::handle_new_imageframe_marker_time_axis_view),track_name, marked_track)) ;
122 Editor::popup_imageframe_edit_menu(int button, int32_t time, ArdourCanvas::Item* ifv, bool with_item)
124 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(clicked_trackview) ;
128 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_selected_imageframe_group() ;
132 ImageFrameView* selected_ifv = ifta->get_view()->get_selected_imageframe_view() ;
133 ifta->popup_imageframe_edit_menu(button, time, selected_ifv, with_item) ;
139 Editor::popup_marker_time_axis_edit_menu(int button, int32_t time, ArdourCanvas::Item* ifv, bool with_item)
141 MarkerTimeAxis* mta = dynamic_cast<MarkerTimeAxis*>(clicked_trackview) ;
145 MarkerView* selected_mv = mta->get_view()->get_selected_time_axis_item() ;
148 mta->popup_marker_time_axis_edit_menu(button,time, selected_mv, with_item) ;
154 Editor::get_named_time_axis(const string & name)
156 TimeAxisView* tav = 0 ;
158 for (TrackViewList::const_iterator i = track_views.begin(); i != track_views.end(); ++i)
160 if (((TimeAxisView*)*i)->name() == name)
162 tav = ((TimeAxisView*)*i) ;
169 /* </CMT Additions file="editor.cc"> */
176 /* <CMT Additions file="editor_canvas_events.cc"> */
178 Editor::canvas_imageframe_item_view_event (GdkEvent *event, ArdourCanvas::Item* item, ImageFrameView *ifv)
181 ImageFrameTimeAxisGroup* iftag = 0 ;
185 case GDK_BUTTON_PRESS:
186 case GDK_2BUTTON_PRESS:
187 case GDK_3BUTTON_PRESS:
188 clicked_trackview = &ifv->get_time_axis_view();
189 iftag = ifv->get_time_axis_group() ;
190 dynamic_cast<ImageFrameTimeAxis*>(clicked_trackview)->get_view()->set_selected_imageframe_view(iftag, ifv);
191 ret = button_press_handler (item, event, ImageFrameItem) ;
193 case GDK_BUTTON_RELEASE:
194 ret = button_release_handler (item, event, ImageFrameItem) ;
196 case GDK_MOTION_NOTIFY:
197 ret = motion_handler (item, event, ImageFrameItem) ;
206 Editor::canvas_imageframe_start_handle_event (GdkEvent *event, ArdourCanvas::Item* item, ImageFrameView *ifv)
209 ImageFrameTimeAxisGroup* iftag = 0 ;
213 case GDK_BUTTON_PRESS:
214 case GDK_2BUTTON_PRESS:
215 case GDK_3BUTTON_PRESS:
216 clicked_trackview = &ifv->get_time_axis_view() ;
217 iftag = ifv->get_time_axis_group() ;
218 dynamic_cast<ImageFrameTimeAxis*>(clicked_trackview)->get_view()->set_selected_imageframe_view(iftag, ifv);
220 ret = button_press_handler (item, event, ImageFrameHandleStartItem) ;
222 case GDK_BUTTON_RELEASE:
223 ret = button_release_handler (item, event, ImageFrameHandleStartItem) ;
225 case GDK_MOTION_NOTIFY:
226 ret = motion_handler (item, event, ImageFrameHandleStartItem) ;
228 case GDK_ENTER_NOTIFY:
229 ret = enter_handler (item, event, ImageFrameHandleStartItem) ;
231 case GDK_LEAVE_NOTIFY:
232 ret = leave_handler (item, event, ImageFrameHandleStartItem) ;
241 Editor::canvas_imageframe_end_handle_event (GdkEvent *event, ArdourCanvas::Item* item, ImageFrameView *ifv)
244 ImageFrameTimeAxisGroup* iftag = 0 ;
248 case GDK_BUTTON_PRESS:
249 case GDK_2BUTTON_PRESS:
250 case GDK_3BUTTON_PRESS:
251 clicked_trackview = &ifv->get_time_axis_view() ;
252 iftag = ifv->get_time_axis_group() ;
253 dynamic_cast<ImageFrameTimeAxis*>(clicked_trackview)->get_view()->set_selected_imageframe_view(iftag, ifv);
255 ret = button_press_handler (item, event, ImageFrameHandleEndItem) ;
257 case GDK_BUTTON_RELEASE:
258 ret = button_release_handler (item, event, ImageFrameHandleEndItem) ;
260 case GDK_MOTION_NOTIFY:
261 ret = motion_handler (item, event, ImageFrameHandleEndItem) ;
263 case GDK_ENTER_NOTIFY:
264 ret = enter_handler (item, event, ImageFrameHandleEndItem) ;
266 case GDK_LEAVE_NOTIFY:
267 ret = leave_handler (item, event, ImageFrameHandleEndItem);
276 Editor::canvas_imageframe_view_event (GdkEvent* event, ArdourCanvas::Item* item, ImageFrameTimeAxis* ifta)
281 case GDK_BUTTON_PRESS:
282 case GDK_2BUTTON_PRESS:
283 case GDK_3BUTTON_PRESS:
284 clicked_trackview = ifta ;
285 ret = button_press_handler (item, event, ImageFrameTimeAxisItem) ;
287 case GDK_BUTTON_RELEASE:
288 ret = button_release_handler (item, event, ImageFrameTimeAxisItem) ;
290 case GDK_MOTION_NOTIFY:
299 Editor::canvas_marker_time_axis_view_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerTimeAxis* mta)
304 case GDK_BUTTON_PRESS:
305 case GDK_2BUTTON_PRESS:
306 case GDK_3BUTTON_PRESS:
307 clicked_trackview = mta ;
308 ret = button_press_handler(item, event, MarkerTimeAxisItem) ;
310 case GDK_BUTTON_RELEASE:
311 ret = button_release_handler(item, event, MarkerTimeAxisItem) ;
313 case GDK_MOTION_NOTIFY:
322 Editor::canvas_markerview_item_view_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerView* mta)
327 case GDK_BUTTON_PRESS:
328 case GDK_2BUTTON_PRESS:
329 case GDK_3BUTTON_PRESS:
330 clicked_trackview = &mta->get_time_axis_view() ;
331 dynamic_cast<MarkerTimeAxis*>(clicked_trackview)->get_view()->set_selected_time_axis_item(mta);
332 ret = button_press_handler(item, event, MarkerViewItem) ;
334 case GDK_BUTTON_RELEASE:
335 ret = button_release_handler(item, event, MarkerViewItem) ;
337 case GDK_MOTION_NOTIFY:
338 ret = motion_handler(item, event, MarkerViewItem) ;
347 Editor::canvas_markerview_start_handle_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerView* mta)
352 case GDK_BUTTON_PRESS:
353 case GDK_2BUTTON_PRESS:
354 case GDK_3BUTTON_PRESS:
355 clicked_trackview = &mta->get_time_axis_view() ;
356 dynamic_cast<MarkerTimeAxis*>(clicked_trackview)->get_view()->set_selected_time_axis_item(mta) ;
357 ret = button_press_handler(item, event, MarkerViewHandleStartItem) ;
359 case GDK_BUTTON_RELEASE:
360 ret = button_release_handler(item, event, MarkerViewHandleStartItem) ;
362 case GDK_MOTION_NOTIFY:
363 ret = motion_handler(item, event, MarkerViewHandleStartItem) ;
365 case GDK_ENTER_NOTIFY:
366 ret = enter_handler(item, event, MarkerViewHandleStartItem) ;
368 case GDK_LEAVE_NOTIFY:
369 ret = leave_handler(item, event, MarkerViewHandleStartItem) ;
378 Editor::canvas_markerview_end_handle_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerView* mta)
383 case GDK_BUTTON_PRESS:
384 case GDK_2BUTTON_PRESS:
385 case GDK_3BUTTON_PRESS:
386 clicked_trackview = &mta->get_time_axis_view() ;
387 dynamic_cast<MarkerTimeAxis*>(clicked_trackview)->get_view()->set_selected_time_axis_item(mta) ;
388 ret = button_press_handler(item, event, MarkerViewHandleEndItem) ;
390 case GDK_BUTTON_RELEASE:
391 ret = button_release_handler(item, event, MarkerViewHandleEndItem) ;
393 case GDK_MOTION_NOTIFY:
394 ret = motion_handler(item, event, MarkerViewHandleEndItem) ;
396 case GDK_ENTER_NOTIFY:
397 ret = enter_handler(item, event, MarkerViewHandleEndItem) ;
399 case GDK_LEAVE_NOTIFY:
400 ret = leave_handler(item, event, MarkerViewHandleEndItem) ;
409 /* </CMT Additions file="editor_canvas_events.cc"> */
413 ---------------------------------------------------------------------------------------------------
414 ---------------------------------------------------------------------------------------------------
415 ---------------------------------------------------------------------------------------------------
420 /* <CMT Additions file="editor_mouse.cc"> */
423 Editor::start_imageframe_grab(ArdourCanvas::Item* item, GdkEvent* event)
425 ImageFrameView* ifv = ((ImageFrameTimeAxis*)clicked_trackview)->get_view()->get_selected_imageframe_view() ;
426 drag_info.copy = false ;
427 drag_info.item = item ;
428 drag_info.data = ifv ;
429 drag_info.motion_callback = &Editor::imageframe_drag_motion_callback;
430 drag_info.finished_callback = &Editor::timeaxis_item_drag_finished_callback;
431 drag_info.last_frame_position = ifv->get_position() ;
433 drag_info.last_trackview = &ifv->get_time_axis_view() ;
435 /* this is subtle. raising the regionview itself won't help,
436 because raise_to_top() just puts the item on the top of
437 its parent's stack. so, we need to put the trackview canvas_display group
438 on the top, since its parent is the whole canvas.
440 however, this hides the measure bars within that particular trackview,
441 so move them to the top afterwards.
444 drag_info.item->raise_to_top();
445 drag_info.last_trackview->canvas_display->raise_to_top();
446 //time_line_group->raise_to_top();
447 cursor_group->raise_to_top ();
451 drag_info.pointer_frame_offset = pixel_to_frame(drag_info.grab_x) - drag_info.last_frame_position;
456 Editor::start_markerview_grab(ArdourCanvas::Item* item, GdkEvent* event)
458 MarkerView* mv = ((MarkerTimeAxis*)clicked_trackview)->get_view()->get_selected_time_axis_item() ;
459 drag_info.copy = false ;
460 drag_info.item = item ;
461 drag_info.data = mv ;
462 drag_info.motion_callback = &Editor::markerview_drag_motion_callback;
463 drag_info.finished_callback = &Editor::timeaxis_item_drag_finished_callback;
464 drag_info.last_frame_position = mv->get_position() ;
466 drag_info.last_trackview = &mv->get_time_axis_view() ;
468 /* this is subtle. raising the regionview itself won't help,
469 because raise_to_top() just puts the item on the top of
470 its parent's stack. so, we need to put the trackview canvas_display group
471 on the top, since its parent is the whole canvas.
473 however, this hides the measure bars within that particular trackview,
474 so move them to the top afterwards.
477 drag_info.item->raise_to_top();
478 drag_info.last_trackview->canvas_display->raise_to_top();
479 //time_line_group->raise_to_top();
480 cursor_group->raise_to_top ();
484 drag_info.pointer_frame_offset = pixel_to_frame(drag_info.grab_x) - drag_info.last_frame_position ;
489 Editor::markerview_drag_motion_callback(ArdourCanvas::Item*, GdkEvent* event)
493 MarkerView* mv = reinterpret_cast<MarkerView*>(drag_info.data) ;
494 nframes_t pending_region_position ;
495 nframes_t pointer_frame ;
497 pointer_frame = event_frame(event, &cx, &cy) ;
499 snap_to(pointer_frame) ;
501 if (pointer_frame > (nframes_t) drag_info.pointer_frame_offset)
503 pending_region_position = pointer_frame - drag_info.pointer_frame_offset ;
504 snap_to(pending_region_position) ;
506 // we dont allow marker items to extend beyond, or in front of the marked items so
507 // cap the value to the marked items position and duration
508 if((pending_region_position + mv->get_duration()) >= ((mv->get_marked_item()->get_position()) + (mv->get_marked_item()->get_duration())))
510 pending_region_position = (mv->get_marked_item()->get_position() + mv->get_marked_item()->get_duration()) - (mv->get_duration()) ;
512 else if(pending_region_position <= mv->get_marked_item()->get_position())
514 pending_region_position = mv->get_marked_item()->get_position() ;
519 pending_region_position = mv->get_marked_item()->get_position() ;
522 drag_info.last_frame_position = pending_region_position ;
524 // we treat this as a special case, usually we want to send the identitiy of the caller
525 // but in this case, that would trigger our socket handler to handle the event, sending
526 // notification to the image compositor. This would be fine, except that we have not
527 // finished the drag, we therefore do not want to sent notification until we have
528 // completed the drag, only then do we want the image compositor notofied.
529 // We therefore set the caller identity to the special case of 0
530 mv->set_position(pending_region_position, 0) ;
532 show_verbose_time_cursor(pending_region_position) ;
536 Editor::imageframe_drag_motion_callback(ArdourCanvas::Item*, GdkEvent* event)
540 ImageFrameView* ifv = reinterpret_cast<ImageFrameView*>(drag_info.data) ;
542 nframes_t pending_region_position;
543 nframes_t pointer_frame;
545 pointer_frame = event_frame(event, &cx, &cy) ;
547 snap_to(pointer_frame) ;
549 if (pointer_frame > (nframes_t) drag_info.pointer_frame_offset)
551 pending_region_position = pointer_frame - drag_info.pointer_frame_offset ;
552 snap_to(pending_region_position) ;
556 pending_region_position = 0 ;
559 drag_info.grab_x = cx;
560 //drag_info.last_frame_position = pending_region_position ;
561 drag_info.current_pointer_frame = pending_region_position ;
563 // we treat this as a special case, usually we want to send the identitiy of the caller
564 // but in this case, that would trigger our socket handler to handle the event, sending
565 // notification to the image compositor. This would be fine, except that we have not
566 // finished the drag, we therefore do not want to sent notification until we have
567 // completed the drag, only then do we want the image compositor notofied.
568 // We therefore set the caller identity to the special case of 0
569 ifv->set_position(pending_region_position, 0) ;
571 show_verbose_time_cursor(pending_region_position) ;
575 Editor::timeaxis_item_drag_finished_callback(ArdourCanvas::Item*, GdkEvent* event)
578 TimeAxisViewItem* tavi = reinterpret_cast<TimeAxisViewItem*>(drag_info.data) ;
580 bool item_x_movement = (drag_info.last_frame_position != tavi->get_position()) ;
582 hide_verbose_canvas_cursor() ;
584 /* no x or y movement either means the regionview hasn't been moved, or has been moved
585 but is back in it's original position/trackview.*/
587 if(!item_x_movement && event && event->type == GDK_BUTTON_RELEASE)
589 /* No motion: either set the current region, or align the clicked region
590 with the current one.
597 /* base the new region position on the current position of the regionview.*/
598 where = drag_info.current_pointer_frame ;
600 // final call to set position after the motion to tell interested parties of the new position
601 tavi->set_position(where, this) ;
605 //where = tavi->get_position() ;
613 Editor::imageframe_start_handle_op(ArdourCanvas::Item* item, GdkEvent* event)
615 // get the selected item from the parent time axis
616 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(clicked_trackview) ;
619 ImageFrameView* ifv = ifta->get_view()->get_selected_imageframe_view() ;
622 fatal << _("programming error: no ImageFrameView selected") << endmsg;
627 drag_info.item = ifv->get_canvas_frame() ;
628 drag_info.data = ifv;
629 drag_info.grab_x = event->motion.x;
630 drag_info.cumulative_x_drag = 0;
631 drag_info.motion_callback = &Editor::imageframe_start_handle_trim_motion ;
632 drag_info.finished_callback = &Editor::imageframe_start_handle_end_trim ;
636 show_verbose_time_cursor(ifv->get_position(), 10) ;
641 Editor::imageframe_end_handle_op(ArdourCanvas::Item* item, GdkEvent* event)
643 // get the selected item from the parent time axis
644 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(clicked_trackview) ;
648 ImageFrameView* ifv = ifta->get_view()->get_selected_imageframe_view() ;
652 fatal << _("programming error: no ImageFrameView selected") << endmsg ;
657 drag_info.item = ifv->get_canvas_frame() ;
658 drag_info.data = ifv ;
659 drag_info.grab_x = event->motion.x ;
660 drag_info.cumulative_x_drag = 0 ;
661 drag_info.motion_callback = &Editor::imageframe_end_handle_trim_motion ;
662 drag_info.finished_callback = &Editor::imageframe_end_handle_end_trim ;
664 start_grab(event, trimmer_cursor) ;
666 show_verbose_time_cursor(ifv->get_position() + ifv->get_duration(), 10) ;
671 Editor::imageframe_start_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* event)
673 ImageFrameView* ifv = reinterpret_cast<ImageFrameView*> (drag_info.data) ;
675 nframes_t start = 0 ;
677 nframes_t pointer_frame = event_frame(event) ;
679 // chekc th eposition of the item is not locked
680 if(!ifv->get_position_locked()) {
681 snap_to(pointer_frame) ;
683 if(pointer_frame != drag_info.last_pointer_frame) {
684 start = ifv->get_position() ;
685 end = ifv->get_position() + ifv->get_duration() ;
687 if (pointer_frame > end) {
690 start = pointer_frame ;
693 // are we getting bigger or smaller?
694 nframes_t new_dur_val = end - start ;
696 // start handle, so a smaller pointer frame increases our component size
697 if(pointer_frame <= drag_info.grab_frame)
699 if(ifv->get_max_duration_active() && (new_dur_val > ifv->get_max_duration()))
701 new_dur_val = ifv->get_max_duration() ;
702 start = end - new_dur_val ;
706 // current values are ok
711 if(ifv->get_min_duration_active() && (new_dur_val < ifv->get_min_duration()))
713 new_dur_val = ifv->get_min_duration() ;
714 start = end - new_dur_val ;
718 // current values are ok
722 drag_info.last_pointer_frame = pointer_frame ;
724 /* re-calculatethe duration and position of the imageframeview */
725 drag_info.cumulative_x_drag = new_dur_val ;
727 // we treat this as a special case, usually we want to send the identitiy of the caller
728 // but in this case, that would trigger our socket handler to handle the event, sending
729 // notification to the image compositor. This would be fine, except that we have not
730 // finished the drag, we therefore do not want to sent notification until we have
731 // completed the drag, only then do we want the image compositor notofied.
732 // We therefore set the caller identity to the special case of 0
733 ifv->set_duration(new_dur_val, 0) ;
734 ifv->set_position(start, 0) ;
738 show_verbose_time_cursor(start, 10) ;
742 Editor::imageframe_start_handle_end_trim(ArdourCanvas::Item* item, GdkEvent* event)
744 ImageFrameView* ifv = reinterpret_cast<ImageFrameView *> (drag_info.data) ;
746 if (drag_info.cumulative_x_drag == 0)
752 nframes_t temp = ifv->get_position() + ifv->get_duration() ;
754 ifv->set_position((nframes_t) (temp - drag_info.cumulative_x_drag), this) ;
755 ifv->set_duration((nframes_t) drag_info.cumulative_x_drag, this) ;
760 Editor::imageframe_end_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* event)
762 ImageFrameView* ifv = reinterpret_cast<ImageFrameView *> (drag_info.data) ;
764 nframes_t start = 0 ;
766 nframes_t pointer_frame = event_frame(event) ;
767 nframes_t new_dur_val = 0 ;
769 snap_to(pointer_frame) ;
771 if (pointer_frame != drag_info.last_pointer_frame)
773 start = ifv->get_position() ;
774 end = ifv->get_position() + ifv->get_duration() ;
775 if (pointer_frame < start)
781 end = pointer_frame ;
784 new_dur_val = end - start ;
786 // are we getting bigger or smaller?
787 if(pointer_frame >= drag_info.last_pointer_frame)
789 if(ifv->get_max_duration_active() && (new_dur_val > ifv->get_max_duration()))
791 new_dur_val = ifv->get_max_duration() ;
796 if(ifv->get_min_duration_active() && (new_dur_val < ifv->get_min_duration()))
798 new_dur_val = ifv->get_min_duration() ;
802 drag_info.last_pointer_frame = pointer_frame ;
803 drag_info.cumulative_x_drag = new_dur_val ;
805 // we treat this as a special case, usually we want to send the identitiy of the caller
806 // but in this case, that would trigger our socket handler to handle the event, sending
807 // notification to the image compositor. This would be fine, except that we have not
808 // finished the drag, we therefore do not want to sent notification until we have
809 // completed the drag, only then do we want the image compositor notofied.
810 // We therefore set the caller identity to the special case of 0
811 ifv->set_duration(new_dur_val, 0) ;
814 show_verbose_time_cursor(new_dur_val, 10) ;
819 Editor::imageframe_end_handle_end_trim (ArdourCanvas::Item* item, GdkEvent* event)
821 ImageFrameView* ifv = reinterpret_cast<ImageFrameView *> (drag_info.data) ;
823 if (drag_info.cumulative_x_drag == 0)
829 nframes_t new_duration = (nframes_t)drag_info.cumulative_x_drag ;
830 if((new_duration <= ifv->get_max_duration()) && (new_duration >= ifv->get_min_duration()))
832 ifv->set_duration(new_duration, this) ;
839 Editor::markerview_item_start_handle_op(ArdourCanvas::Item* item, GdkEvent* event)
841 MarkerView* mv = reinterpret_cast<MarkerTimeAxis*>(clicked_trackview)->get_view()->get_selected_time_axis_item() ;
845 fatal << _("programming error: no MarkerView selected") << endmsg ;
850 drag_info.item = mv->get_canvas_frame() ;
852 drag_info.grab_x = event->motion.x;
854 drag_info.cumulative_x_drag = 0 ;
855 drag_info.motion_callback = &Editor::markerview_start_handle_trim_motion ;
856 drag_info.finished_callback = &Editor::markerview_start_handle_end_trim ;
858 start_grab(event, trimmer_cursor) ;
862 Editor::markerview_item_end_handle_op(ArdourCanvas::Item* item, GdkEvent* event)
864 MarkerView* mv = reinterpret_cast<MarkerTimeAxis*>(clicked_trackview)->get_view()->get_selected_time_axis_item() ;
867 fatal << _("programming error: no MarkerView selected") << endmsg ;
872 drag_info.item = mv->get_canvas_frame() ;
873 drag_info.data = mv ;
874 drag_info.grab_x = event->motion.x ;
875 drag_info.cumulative_x_drag = 0 ;
877 drag_info.motion_callback = &Editor::markerview_end_handle_trim_motion ;
878 drag_info.finished_callback = &Editor::markerview_end_handle_end_trim ;
880 start_grab(event, trimmer_cursor) ;
885 Editor::markerview_start_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* event)
887 MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
889 nframes_t start = 0 ;
891 nframes_t pointer_frame = event_frame(event) ;
893 // chekc th eposition of the item is not locked
894 if(!mv->get_position_locked())
896 snap_to(pointer_frame) ;
897 if(pointer_frame != drag_info.last_pointer_frame)
899 start = mv->get_position() ;
900 end = mv->get_position() + mv->get_duration() ;
902 if (pointer_frame > end)
908 start = pointer_frame ;
911 // are we getting bigger or smaller?
912 nframes_t new_dur_val = end - start ;
914 if(pointer_frame <= drag_info.grab_frame)
916 if(mv->get_max_duration_active() && (new_dur_val > mv->get_max_duration()))
918 new_dur_val = mv->get_max_duration() ;
919 start = end - new_dur_val ;
923 // current values are ok
928 if(mv->get_min_duration_active() && (new_dur_val < mv->get_min_duration()))
930 new_dur_val = mv->get_min_duration() ;
931 start = end - new_dur_val ;
935 // current values are ok
939 drag_info.last_pointer_frame = pointer_frame ;
941 /* re-calculatethe duration and position of the imageframeview */
942 drag_info.cumulative_x_drag = new_dur_val ;
944 // we treat this as a special case, usually we want to send the identitiy of the caller
945 // but in this case, that would trigger our socket handler to handle the event, sending
946 // notification to the image compositor. This would be fine, except that we have not
947 // finished the drag, we therefore do not want to sent notification until we have
948 // completed the drag, only then do we want the image compositor notofied.
949 // We therefore set the caller identity to the special case of 0
950 mv->set_duration(new_dur_val, 0) ;
951 mv->set_position(start, 0) ;
955 show_verbose_time_cursor(start, 10) ;
959 Editor::markerview_start_handle_end_trim(ArdourCanvas::Item* item, GdkEvent* event)
961 MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
963 if (drag_info.cumulative_x_drag == 0)
969 nframes_t temp = mv->get_position() + mv->get_duration() ;
971 mv->set_position((nframes_t) (temp - drag_info.cumulative_x_drag), this) ;
972 mv->set_duration((nframes_t) drag_info.cumulative_x_drag, this) ;
977 Editor::markerview_end_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* event)
979 MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
981 nframes_t start = 0 ;
983 nframes_t pointer_frame = event_frame(event) ;
984 nframes_t new_dur_val = 0 ;
986 snap_to(pointer_frame) ;
988 if (pointer_frame != drag_info.last_pointer_frame)
990 start = mv->get_position() ;
991 end = mv->get_position() + mv->get_duration() ;
993 if(pointer_frame < start)
999 end = pointer_frame ;
1002 new_dur_val = end - start ;
1004 // are we getting bigger or smaller?
1005 if(pointer_frame >= drag_info.last_pointer_frame)
1007 // we cant extend beyond the item we are marking
1008 ImageFrameView* marked_item = mv->get_marked_item() ;
1009 nframes_t marked_end = marked_item->get_position() + marked_item->get_duration() ;
1011 if(mv->get_max_duration_active() && (new_dur_val > mv->get_max_duration()))
1013 if((start + mv->get_max_duration()) > marked_end)
1015 new_dur_val = marked_end - start ;
1019 new_dur_val = mv->get_max_duration() ;
1022 else if(end > marked_end)
1024 new_dur_val = marked_end - start ;
1029 if(mv->get_min_duration_active() && (new_dur_val < mv->get_min_duration()))
1031 new_dur_val = mv->get_min_duration() ;
1036 drag_info.last_pointer_frame = pointer_frame ;
1037 drag_info.cumulative_x_drag = new_dur_val ;
1039 // we treat this as a special case, usually we want to send the identitiy of the caller
1040 // but in this case, that would trigger our socket handler to handle the event, sending
1041 // notification to the image compositor. This would be fine, except that we have not
1042 // finished the drag, we therefore do not want to sent notification until we have
1043 // completed the drag, only then do we want the image compositor notofied.
1044 // We therefore set the caller identity to the special case of 0
1045 mv->set_duration(new_dur_val, 0) ;
1048 show_verbose_time_cursor(new_dur_val, 10) ;
1053 Editor::markerview_end_handle_end_trim (ArdourCanvas::Item* item, GdkEvent* event)
1055 MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
1057 if (drag_info.cumulative_x_drag == 0)
1063 nframes_t new_duration = (nframes_t)drag_info.cumulative_x_drag ;
1064 mv->set_duration(new_duration, this) ;
1069 /* </CMT Additions file="editor_mouse.cc"> */
1077 /* <CMT Additions file="editor_route_list.cc"> */
1080 Editor::handle_new_imageframe_time_axis_view(const string & track_name, void* src)
1082 ImageFrameTimeAxis* iftav ;
1083 iftav = new ImageFrameTimeAxis(track_name, *this, *session, track_canvas) ;
1084 iftav->set_time_axis_name(track_name, this) ;
1085 track_views.push_back(iftav) ;
1087 TreeModel::Row row = *(route_display_model->append());
1089 row[route_display_columns.text] = iftav->name();
1090 row[route_display_columns.tv] = iftav;
1091 route_list_display.get_selection()->select (row);
1093 iftav->GoingAway.connect(bind(mem_fun(*this, &Editor::remove_route), (TimeAxisView*)iftav)) ;
1094 iftav->gui_changed.connect(mem_fun(*this, &Editor::handle_gui_changes)) ;
1098 Editor::handle_new_imageframe_marker_time_axis_view(const string & track_name, TimeAxisView* marked_track)
1100 MarkerTimeAxis* mta = new MarkerTimeAxis (*this, *this->current_session(), track_canvas, track_name, marked_track) ;
1101 ((ImageFrameTimeAxis*)marked_track)->add_marker_time_axis(mta, this) ;
1102 track_views.push_back(mta) ;
1104 TreeModel::Row row = *(route_display_model->append());
1106 row[route_display_columns.text] = mta->name();
1107 row[route_display_columns.tv] = mta;
1108 route_list_display.get_selection()->select (row);
1110 mta->GoingAway.connect(bind(mem_fun(*this, &Editor::remove_route), (TimeAxisView*)mta)) ;
1114 /* </CMT Additions file="editor_route_list.cc"> */