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"
49 /* <CMT Additions file="editor.cc"> */
52 Editor::add_imageframe_time_axis(const string & track_name, void* src)
54 // check for duplicate name
55 if(get_named_time_axis(track_name))
57 warning << "Repeated time axis name" << std::endl ;
61 Gtkmm2ext::UI::instance()->call_slot(bind(mem_fun(*this, &Editor::handle_new_imageframe_time_axis_view),track_name, src)) ;
66 Editor::connect_to_image_compositor()
68 if(image_socket_listener == 0)
70 image_socket_listener = ImageFrameSocketHandler::create_instance(*this) ;
73 if(image_socket_listener->is_connected() == true)
78 // XXX should really put this somewhere safe
79 const char * host_ip = "127.0.0.1" ;
81 bool retcode = image_socket_listener->connect(host_ip, ardourvis::DEFAULT_PORT) ;
85 // XXX need to get some return status here
86 warning << "Image Compositor Connection attempt failed" << std::endl ;
90 // add the socket to the gui loop, and keep the retuned tag value of the input
91 gint tag = gdk_input_add(image_socket_listener->get_socket_descriptor(), GDK_INPUT_READ,ImageFrameSocketHandler::image_socket_callback,image_socket_listener) ;
92 image_socket_listener->set_gdk_input_tag(tag) ;
96 Editor::scroll_timeaxis_to_imageframe_item(const TimeAxisViewItem* item)
99 //nframes_t offset = static_cast<nframes_t>(frames_per_unit * (edit_hscroll_slider_width/2)) ;
100 nframes_t offset = 0;
102 nframes_t x_pos = 0 ;
103 if(item->get_position() < offset)
109 x_pos = item->get_position() - offset + (item->get_duration() / 2) ;
112 reposition_x_origin(x_pos) ;
116 Editor::add_imageframe_marker_time_axis(const string & track_name, TimeAxisView* marked_track, void* src)
118 // Can we only bind 2 data Items?
119 // @todo we really want to bind the src attribute too, for the moment tracks can only be added remotely,
120 // so this is not too much of an issue, however will need to be looked at again
121 Gtkmm2ext::UI::instance()->call_slot(sigc::bind(mem_fun(*this, &Editor::handle_new_imageframe_marker_time_axis_view),track_name, marked_track)) ;
125 Editor::popup_imageframe_edit_menu(int button, int32_t time, ArdourCanvas::Item* ifv, bool with_item)
127 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(clicked_trackview) ;
131 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_selected_imageframe_group() ;
135 ImageFrameView* selected_ifv = ifta->get_view()->get_selected_imageframe_view() ;
136 ifta->popup_imageframe_edit_menu(button, time, selected_ifv, with_item) ;
142 Editor::popup_marker_time_axis_edit_menu(int button, int32_t time, ArdourCanvas::Item* ifv, bool with_item)
144 MarkerTimeAxis* mta = dynamic_cast<MarkerTimeAxis*>(clicked_trackview) ;
148 MarkerView* selected_mv = mta->get_view()->get_selected_time_axis_item() ;
151 mta->popup_marker_time_axis_edit_menu(button,time, selected_mv, with_item) ;
157 Editor::get_named_time_axis(const string & name)
159 TimeAxisView* tav = 0 ;
161 for (TrackViewList::const_iterator i = track_views.begin(); i != track_views.end(); ++i)
163 if (((TimeAxisView*)*i)->name() == name)
165 tav = ((TimeAxisView*)*i) ;
172 /* </CMT Additions file="editor.cc"> */
179 /* <CMT Additions file="editor_canvas_events.cc"> */
181 Editor::canvas_imageframe_item_view_event (GdkEvent *event, ArdourCanvas::Item* item, ImageFrameView *ifv)
184 ImageFrameTimeAxisGroup* iftag = 0 ;
188 case GDK_BUTTON_PRESS:
189 case GDK_2BUTTON_PRESS:
190 case GDK_3BUTTON_PRESS:
191 clicked_trackview = &ifv->get_time_axis_view();
192 iftag = ifv->get_time_axis_group() ;
193 dynamic_cast<ImageFrameTimeAxis*>(clicked_trackview)->get_view()->set_selected_imageframe_view(iftag, ifv);
194 ret = button_press_handler (item, event, ImageFrameItem) ;
196 case GDK_BUTTON_RELEASE:
197 ret = button_release_handler (item, event, ImageFrameItem) ;
199 case GDK_MOTION_NOTIFY:
200 ret = motion_handler (item, event, ImageFrameItem) ;
209 Editor::canvas_imageframe_start_handle_event (GdkEvent *event, ArdourCanvas::Item* item, ImageFrameView *ifv)
212 ImageFrameTimeAxisGroup* iftag = 0 ;
216 case GDK_BUTTON_PRESS:
217 case GDK_2BUTTON_PRESS:
218 case GDK_3BUTTON_PRESS:
219 clicked_trackview = &ifv->get_time_axis_view() ;
220 iftag = ifv->get_time_axis_group() ;
221 dynamic_cast<ImageFrameTimeAxis*>(clicked_trackview)->get_view()->set_selected_imageframe_view(iftag, ifv);
223 ret = button_press_handler (item, event, ImageFrameHandleStartItem) ;
225 case GDK_BUTTON_RELEASE:
226 ret = button_release_handler (item, event, ImageFrameHandleStartItem) ;
228 case GDK_MOTION_NOTIFY:
229 ret = motion_handler (item, event, ImageFrameHandleStartItem) ;
231 case GDK_ENTER_NOTIFY:
232 ret = enter_handler (item, event, ImageFrameHandleStartItem) ;
234 case GDK_LEAVE_NOTIFY:
235 ret = leave_handler (item, event, ImageFrameHandleStartItem) ;
244 Editor::canvas_imageframe_end_handle_event (GdkEvent *event, ArdourCanvas::Item* item, ImageFrameView *ifv)
247 ImageFrameTimeAxisGroup* iftag = 0 ;
251 case GDK_BUTTON_PRESS:
252 case GDK_2BUTTON_PRESS:
253 case GDK_3BUTTON_PRESS:
254 clicked_trackview = &ifv->get_time_axis_view() ;
255 iftag = ifv->get_time_axis_group() ;
256 dynamic_cast<ImageFrameTimeAxis*>(clicked_trackview)->get_view()->set_selected_imageframe_view(iftag, ifv);
258 ret = button_press_handler (item, event, ImageFrameHandleEndItem) ;
260 case GDK_BUTTON_RELEASE:
261 ret = button_release_handler (item, event, ImageFrameHandleEndItem) ;
263 case GDK_MOTION_NOTIFY:
264 ret = motion_handler (item, event, ImageFrameHandleEndItem) ;
266 case GDK_ENTER_NOTIFY:
267 ret = enter_handler (item, event, ImageFrameHandleEndItem) ;
269 case GDK_LEAVE_NOTIFY:
270 ret = leave_handler (item, event, ImageFrameHandleEndItem);
279 Editor::canvas_imageframe_view_event (GdkEvent* event, ArdourCanvas::Item* item, ImageFrameTimeAxis* ifta)
284 case GDK_BUTTON_PRESS:
285 case GDK_2BUTTON_PRESS:
286 case GDK_3BUTTON_PRESS:
287 clicked_trackview = ifta ;
288 ret = button_press_handler (item, event, ImageFrameTimeAxisItem) ;
290 case GDK_BUTTON_RELEASE:
291 ret = button_release_handler (item, event, ImageFrameTimeAxisItem) ;
293 case GDK_MOTION_NOTIFY:
302 Editor::canvas_marker_time_axis_view_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerTimeAxis* mta)
307 case GDK_BUTTON_PRESS:
308 case GDK_2BUTTON_PRESS:
309 case GDK_3BUTTON_PRESS:
310 clicked_trackview = mta ;
311 ret = button_press_handler(item, event, MarkerTimeAxisItem) ;
313 case GDK_BUTTON_RELEASE:
314 ret = button_release_handler(item, event, MarkerTimeAxisItem) ;
316 case GDK_MOTION_NOTIFY:
325 Editor::canvas_markerview_item_view_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerView* mta)
330 case GDK_BUTTON_PRESS:
331 case GDK_2BUTTON_PRESS:
332 case GDK_3BUTTON_PRESS:
333 clicked_trackview = &mta->get_time_axis_view() ;
334 dynamic_cast<MarkerTimeAxis*>(clicked_trackview)->get_view()->set_selected_time_axis_item(mta);
335 ret = button_press_handler(item, event, MarkerViewItem) ;
337 case GDK_BUTTON_RELEASE:
338 ret = button_release_handler(item, event, MarkerViewItem) ;
340 case GDK_MOTION_NOTIFY:
341 ret = motion_handler(item, event, MarkerViewItem) ;
350 Editor::canvas_markerview_start_handle_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerView* mta)
355 case GDK_BUTTON_PRESS:
356 case GDK_2BUTTON_PRESS:
357 case GDK_3BUTTON_PRESS:
358 clicked_trackview = &mta->get_time_axis_view() ;
359 dynamic_cast<MarkerTimeAxis*>(clicked_trackview)->get_view()->set_selected_time_axis_item(mta) ;
360 ret = button_press_handler(item, event, MarkerViewHandleStartItem) ;
362 case GDK_BUTTON_RELEASE:
363 ret = button_release_handler(item, event, MarkerViewHandleStartItem) ;
365 case GDK_MOTION_NOTIFY:
366 ret = motion_handler(item, event, MarkerViewHandleStartItem) ;
368 case GDK_ENTER_NOTIFY:
369 ret = enter_handler(item, event, MarkerViewHandleStartItem) ;
371 case GDK_LEAVE_NOTIFY:
372 ret = leave_handler(item, event, MarkerViewHandleStartItem) ;
381 Editor::canvas_markerview_end_handle_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerView* mta)
386 case GDK_BUTTON_PRESS:
387 case GDK_2BUTTON_PRESS:
388 case GDK_3BUTTON_PRESS:
389 clicked_trackview = &mta->get_time_axis_view() ;
390 dynamic_cast<MarkerTimeAxis*>(clicked_trackview)->get_view()->set_selected_time_axis_item(mta) ;
391 ret = button_press_handler(item, event, MarkerViewHandleEndItem) ;
393 case GDK_BUTTON_RELEASE:
394 ret = button_release_handler(item, event, MarkerViewHandleEndItem) ;
396 case GDK_MOTION_NOTIFY:
397 ret = motion_handler(item, event, MarkerViewHandleEndItem) ;
399 case GDK_ENTER_NOTIFY:
400 ret = enter_handler(item, event, MarkerViewHandleEndItem) ;
402 case GDK_LEAVE_NOTIFY:
403 ret = leave_handler(item, event, MarkerViewHandleEndItem) ;
412 /* </CMT Additions file="editor_canvas_events.cc"> */
416 ---------------------------------------------------------------------------------------------------
417 ---------------------------------------------------------------------------------------------------
418 ---------------------------------------------------------------------------------------------------
423 /* <CMT Additions file="editor_mouse.cc"> */
426 Editor::start_imageframe_grab(ArdourCanvas::Item* item, GdkEvent* event)
428 ImageFrameView* ifv = ((ImageFrameTimeAxis*)clicked_trackview)->get_view()->get_selected_imageframe_view() ;
429 drag_info.copy = false ;
430 drag_info.item = item ;
431 drag_info.data = ifv ;
432 drag_info.motion_callback = &Editor::imageframe_drag_motion_callback;
433 drag_info.finished_callback = &Editor::timeaxis_item_drag_finished_callback;
434 drag_info.last_frame_position = ifv->get_position() ;
436 drag_info.last_trackview = &ifv->get_time_axis_view() ;
438 /* this is subtle. raising the regionview itself won't help,
439 because raise_to_top() just puts the item on the top of
440 its parent's stack. so, we need to put the trackview canvas_display group
441 on the top, since its parent is the whole canvas.
443 however, this hides the measure bars within that particular trackview,
444 so move them to the top afterwards.
447 drag_info.item->raise_to_top();
448 drag_info.last_trackview->canvas_display->raise_to_top();
449 //time_line_group->raise_to_top();
450 cursor_group->raise_to_top ();
454 drag_info.pointer_frame_offset = pixel_to_frame(drag_info.grab_x) - drag_info.last_frame_position;
459 Editor::start_markerview_grab(ArdourCanvas::Item* item, GdkEvent* event)
461 MarkerView* mv = ((MarkerTimeAxis*)clicked_trackview)->get_view()->get_selected_time_axis_item() ;
462 drag_info.copy = false ;
463 drag_info.item = item ;
464 drag_info.data = mv ;
465 drag_info.motion_callback = &Editor::markerview_drag_motion_callback;
466 drag_info.finished_callback = &Editor::timeaxis_item_drag_finished_callback;
467 drag_info.last_frame_position = mv->get_position() ;
469 drag_info.last_trackview = &mv->get_time_axis_view() ;
471 /* this is subtle. raising the regionview itself won't help,
472 because raise_to_top() just puts the item on the top of
473 its parent's stack. so, we need to put the trackview canvas_display group
474 on the top, since its parent is the whole canvas.
476 however, this hides the measure bars within that particular trackview,
477 so move them to the top afterwards.
480 drag_info.item->raise_to_top();
481 drag_info.last_trackview->canvas_display->raise_to_top();
482 //time_line_group->raise_to_top();
483 cursor_group->raise_to_top ();
487 drag_info.pointer_frame_offset = pixel_to_frame(drag_info.grab_x) - drag_info.last_frame_position ;
492 Editor::markerview_drag_motion_callback(ArdourCanvas::Item*, GdkEvent* event)
496 MarkerView* mv = reinterpret_cast<MarkerView*>(drag_info.data) ;
497 nframes_t pending_region_position ;
498 nframes_t pointer_frame ;
500 pointer_frame = event_frame(event, &cx, &cy) ;
502 snap_to(pointer_frame) ;
504 if (pointer_frame > (nframes_t) drag_info.pointer_frame_offset)
506 pending_region_position = pointer_frame - drag_info.pointer_frame_offset ;
507 snap_to(pending_region_position) ;
509 // we dont allow marker items to extend beyond, or in front of the marked items so
510 // cap the value to the marked items position and duration
511 if((pending_region_position + mv->get_duration()) >= ((mv->get_marked_item()->get_position()) + (mv->get_marked_item()->get_duration())))
513 pending_region_position = (mv->get_marked_item()->get_position() + mv->get_marked_item()->get_duration()) - (mv->get_duration()) ;
515 else if(pending_region_position <= mv->get_marked_item()->get_position())
517 pending_region_position = mv->get_marked_item()->get_position() ;
522 pending_region_position = mv->get_marked_item()->get_position() ;
525 drag_info.last_frame_position = pending_region_position ;
527 // we treat this as a special case, usually we want to send the identitiy of the caller
528 // but in this case, that would trigger our socket handler to handle the event, sending
529 // notification to the image compositor. This would be fine, except that we have not
530 // finished the drag, we therefore do not want to sent notification until we have
531 // completed the drag, only then do we want the image compositor notofied.
532 // We therefore set the caller identity to the special case of 0
533 mv->set_position(pending_region_position, 0) ;
535 show_verbose_time_cursor(pending_region_position) ;
539 Editor::imageframe_drag_motion_callback(ArdourCanvas::Item*, GdkEvent* event)
543 ImageFrameView* ifv = reinterpret_cast<ImageFrameView*>(drag_info.data) ;
545 nframes_t pending_region_position;
546 nframes_t pointer_frame;
548 pointer_frame = event_frame(event, &cx, &cy) ;
550 snap_to(pointer_frame) ;
552 if (pointer_frame > (nframes_t) drag_info.pointer_frame_offset)
554 pending_region_position = pointer_frame - drag_info.pointer_frame_offset ;
555 snap_to(pending_region_position) ;
559 pending_region_position = 0 ;
562 drag_info.grab_x = cx;
563 //drag_info.last_frame_position = pending_region_position ;
564 drag_info.current_pointer_frame = pending_region_position ;
566 // we treat this as a special case, usually we want to send the identitiy of the caller
567 // but in this case, that would trigger our socket handler to handle the event, sending
568 // notification to the image compositor. This would be fine, except that we have not
569 // finished the drag, we therefore do not want to sent notification until we have
570 // completed the drag, only then do we want the image compositor notofied.
571 // We therefore set the caller identity to the special case of 0
572 ifv->set_position(pending_region_position, 0) ;
574 show_verbose_time_cursor(pending_region_position) ;
578 Editor::timeaxis_item_drag_finished_callback(ArdourCanvas::Item*, GdkEvent* event)
581 TimeAxisViewItem* tavi = reinterpret_cast<TimeAxisViewItem*>(drag_info.data) ;
583 bool item_x_movement = (drag_info.last_frame_position != tavi->get_position()) ;
585 hide_verbose_canvas_cursor() ;
587 /* no x or y movement either means the regionview hasn't been moved, or has been moved
588 but is back in it's original position/trackview.*/
590 if(!item_x_movement && event && event->type == GDK_BUTTON_RELEASE)
592 /* No motion: either set the current region, or align the clicked region
593 with the current one.
600 /* base the new region position on the current position of the regionview.*/
601 where = drag_info.current_pointer_frame ;
603 // final call to set position after the motion to tell interested parties of the new position
604 tavi->set_position(where, this) ;
608 //where = tavi->get_position() ;
616 Editor::imageframe_start_handle_op(ArdourCanvas::Item* item, GdkEvent* event)
618 // get the selected item from the parent time axis
619 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(clicked_trackview) ;
622 ImageFrameView* ifv = ifta->get_view()->get_selected_imageframe_view() ;
625 fatal << _("programming error: no ImageFrameView selected") << endmsg;
630 drag_info.item = ifv->get_canvas_frame() ;
631 drag_info.data = ifv;
632 drag_info.grab_x = event->motion.x;
633 drag_info.cumulative_x_drag = 0;
634 drag_info.motion_callback = &Editor::imageframe_start_handle_trim_motion ;
635 drag_info.finished_callback = &Editor::imageframe_start_handle_end_trim ;
639 show_verbose_time_cursor(ifv->get_position(), 10) ;
644 Editor::imageframe_end_handle_op(ArdourCanvas::Item* item, GdkEvent* event)
646 // get the selected item from the parent time axis
647 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(clicked_trackview) ;
651 ImageFrameView* ifv = ifta->get_view()->get_selected_imageframe_view() ;
655 fatal << _("programming error: no ImageFrameView selected") << endmsg ;
660 drag_info.item = ifv->get_canvas_frame() ;
661 drag_info.data = ifv ;
662 drag_info.grab_x = event->motion.x ;
663 drag_info.cumulative_x_drag = 0 ;
664 drag_info.motion_callback = &Editor::imageframe_end_handle_trim_motion ;
665 drag_info.finished_callback = &Editor::imageframe_end_handle_end_trim ;
667 start_grab(event, trimmer_cursor) ;
669 show_verbose_time_cursor(ifv->get_position() + ifv->get_duration(), 10) ;
674 Editor::imageframe_start_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* event)
676 ImageFrameView* ifv = reinterpret_cast<ImageFrameView*> (drag_info.data) ;
678 nframes_t start = 0 ;
680 nframes_t pointer_frame = event_frame(event) ;
682 // chekc th eposition of the item is not locked
683 if(!ifv->get_position_locked()) {
684 snap_to(pointer_frame) ;
686 if(pointer_frame != drag_info.last_pointer_frame) {
687 start = ifv->get_position() ;
688 end = ifv->get_position() + ifv->get_duration() ;
690 if (pointer_frame > end) {
693 start = pointer_frame ;
696 // are we getting bigger or smaller?
697 nframes_t new_dur_val = end - start ;
699 // start handle, so a smaller pointer frame increases our component size
700 if(pointer_frame <= drag_info.grab_frame)
702 if(ifv->get_max_duration_active() && (new_dur_val > ifv->get_max_duration()))
704 new_dur_val = ifv->get_max_duration() ;
705 start = end - new_dur_val ;
709 // current values are ok
714 if(ifv->get_min_duration_active() && (new_dur_val < ifv->get_min_duration()))
716 new_dur_val = ifv->get_min_duration() ;
717 start = end - new_dur_val ;
721 // current values are ok
725 drag_info.last_pointer_frame = pointer_frame ;
727 /* re-calculatethe duration and position of the imageframeview */
728 drag_info.cumulative_x_drag = new_dur_val ;
730 // we treat this as a special case, usually we want to send the identitiy of the caller
731 // but in this case, that would trigger our socket handler to handle the event, sending
732 // notification to the image compositor. This would be fine, except that we have not
733 // finished the drag, we therefore do not want to sent notification until we have
734 // completed the drag, only then do we want the image compositor notofied.
735 // We therefore set the caller identity to the special case of 0
736 ifv->set_duration(new_dur_val, 0) ;
737 ifv->set_position(start, 0) ;
741 show_verbose_time_cursor(start, 10) ;
745 Editor::imageframe_start_handle_end_trim(ArdourCanvas::Item* item, GdkEvent* event)
747 ImageFrameView* ifv = reinterpret_cast<ImageFrameView *> (drag_info.data) ;
749 if (drag_info.cumulative_x_drag == 0)
755 nframes_t temp = ifv->get_position() + ifv->get_duration() ;
757 ifv->set_position((nframes_t) (temp - drag_info.cumulative_x_drag), this) ;
758 ifv->set_duration((nframes_t) drag_info.cumulative_x_drag, this) ;
763 Editor::imageframe_end_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* event)
765 ImageFrameView* ifv = reinterpret_cast<ImageFrameView *> (drag_info.data) ;
767 nframes_t start = 0 ;
769 nframes_t pointer_frame = event_frame(event) ;
770 nframes_t new_dur_val = 0 ;
772 snap_to(pointer_frame) ;
774 if (pointer_frame != drag_info.last_pointer_frame)
776 start = ifv->get_position() ;
777 end = ifv->get_position() + ifv->get_duration() ;
778 if (pointer_frame < start)
784 end = pointer_frame ;
787 new_dur_val = end - start ;
789 // are we getting bigger or smaller?
790 if(pointer_frame >= drag_info.last_pointer_frame)
792 if(ifv->get_max_duration_active() && (new_dur_val > ifv->get_max_duration()))
794 new_dur_val = ifv->get_max_duration() ;
799 if(ifv->get_min_duration_active() && (new_dur_val < ifv->get_min_duration()))
801 new_dur_val = ifv->get_min_duration() ;
805 drag_info.last_pointer_frame = pointer_frame ;
806 drag_info.cumulative_x_drag = new_dur_val ;
808 // we treat this as a special case, usually we want to send the identitiy of the caller
809 // but in this case, that would trigger our socket handler to handle the event, sending
810 // notification to the image compositor. This would be fine, except that we have not
811 // finished the drag, we therefore do not want to sent notification until we have
812 // completed the drag, only then do we want the image compositor notofied.
813 // We therefore set the caller identity to the special case of 0
814 ifv->set_duration(new_dur_val, 0) ;
817 show_verbose_time_cursor(new_dur_val, 10) ;
822 Editor::imageframe_end_handle_end_trim (ArdourCanvas::Item* item, GdkEvent* event)
824 ImageFrameView* ifv = reinterpret_cast<ImageFrameView *> (drag_info.data) ;
826 if (drag_info.cumulative_x_drag == 0)
832 nframes_t new_duration = (nframes_t)drag_info.cumulative_x_drag ;
833 if((new_duration <= ifv->get_max_duration()) && (new_duration >= ifv->get_min_duration()))
835 ifv->set_duration(new_duration, this) ;
842 Editor::markerview_item_start_handle_op(ArdourCanvas::Item* item, GdkEvent* event)
844 MarkerView* mv = reinterpret_cast<MarkerTimeAxis*>(clicked_trackview)->get_view()->get_selected_time_axis_item() ;
848 fatal << _("programming error: no MarkerView selected") << endmsg ;
853 drag_info.item = mv->get_canvas_frame() ;
855 drag_info.grab_x = event->motion.x;
857 drag_info.cumulative_x_drag = 0 ;
858 drag_info.motion_callback = &Editor::markerview_start_handle_trim_motion ;
859 drag_info.finished_callback = &Editor::markerview_start_handle_end_trim ;
861 start_grab(event, trimmer_cursor) ;
865 Editor::markerview_item_end_handle_op(ArdourCanvas::Item* item, GdkEvent* event)
867 MarkerView* mv = reinterpret_cast<MarkerTimeAxis*>(clicked_trackview)->get_view()->get_selected_time_axis_item() ;
870 fatal << _("programming error: no MarkerView selected") << endmsg ;
875 drag_info.item = mv->get_canvas_frame() ;
876 drag_info.data = mv ;
877 drag_info.grab_x = event->motion.x ;
878 drag_info.cumulative_x_drag = 0 ;
880 drag_info.motion_callback = &Editor::markerview_end_handle_trim_motion ;
881 drag_info.finished_callback = &Editor::markerview_end_handle_end_trim ;
883 start_grab(event, trimmer_cursor) ;
888 Editor::markerview_start_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* event)
890 MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
892 nframes_t start = 0 ;
894 nframes_t pointer_frame = event_frame(event) ;
896 // chekc th eposition of the item is not locked
897 if(!mv->get_position_locked())
899 snap_to(pointer_frame) ;
900 if(pointer_frame != drag_info.last_pointer_frame)
902 start = mv->get_position() ;
903 end = mv->get_position() + mv->get_duration() ;
905 if (pointer_frame > end)
911 start = pointer_frame ;
914 // are we getting bigger or smaller?
915 nframes_t new_dur_val = end - start ;
917 if(pointer_frame <= drag_info.grab_frame)
919 if(mv->get_max_duration_active() && (new_dur_val > mv->get_max_duration()))
921 new_dur_val = mv->get_max_duration() ;
922 start = end - new_dur_val ;
926 // current values are ok
931 if(mv->get_min_duration_active() && (new_dur_val < mv->get_min_duration()))
933 new_dur_val = mv->get_min_duration() ;
934 start = end - new_dur_val ;
938 // current values are ok
942 drag_info.last_pointer_frame = pointer_frame ;
944 /* re-calculatethe duration and position of the imageframeview */
945 drag_info.cumulative_x_drag = new_dur_val ;
947 // we treat this as a special case, usually we want to send the identitiy of the caller
948 // but in this case, that would trigger our socket handler to handle the event, sending
949 // notification to the image compositor. This would be fine, except that we have not
950 // finished the drag, we therefore do not want to sent notification until we have
951 // completed the drag, only then do we want the image compositor notofied.
952 // We therefore set the caller identity to the special case of 0
953 mv->set_duration(new_dur_val, 0) ;
954 mv->set_position(start, 0) ;
958 show_verbose_time_cursor(start, 10) ;
962 Editor::markerview_start_handle_end_trim(ArdourCanvas::Item* item, GdkEvent* event)
964 MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
966 if (drag_info.cumulative_x_drag == 0)
972 nframes_t temp = mv->get_position() + mv->get_duration() ;
974 mv->set_position((nframes_t) (temp - drag_info.cumulative_x_drag), this) ;
975 mv->set_duration((nframes_t) drag_info.cumulative_x_drag, this) ;
980 Editor::markerview_end_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* event)
982 MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
984 nframes_t start = 0 ;
986 nframes_t pointer_frame = event_frame(event) ;
987 nframes_t new_dur_val = 0 ;
989 snap_to(pointer_frame) ;
991 if (pointer_frame != drag_info.last_pointer_frame)
993 start = mv->get_position() ;
994 end = mv->get_position() + mv->get_duration() ;
996 if(pointer_frame < start)
1002 end = pointer_frame ;
1005 new_dur_val = end - start ;
1007 // are we getting bigger or smaller?
1008 if(pointer_frame >= drag_info.last_pointer_frame)
1010 // we cant extend beyond the item we are marking
1011 ImageFrameView* marked_item = mv->get_marked_item() ;
1012 nframes_t marked_end = marked_item->get_position() + marked_item->get_duration() ;
1014 if(mv->get_max_duration_active() && (new_dur_val > mv->get_max_duration()))
1016 if((start + mv->get_max_duration()) > marked_end)
1018 new_dur_val = marked_end - start ;
1022 new_dur_val = mv->get_max_duration() ;
1025 else if(end > marked_end)
1027 new_dur_val = marked_end - start ;
1032 if(mv->get_min_duration_active() && (new_dur_val < mv->get_min_duration()))
1034 new_dur_val = mv->get_min_duration() ;
1039 drag_info.last_pointer_frame = pointer_frame ;
1040 drag_info.cumulative_x_drag = new_dur_val ;
1042 // we treat this as a special case, usually we want to send the identitiy of the caller
1043 // but in this case, that would trigger our socket handler to handle the event, sending
1044 // notification to the image compositor. This would be fine, except that we have not
1045 // finished the drag, we therefore do not want to sent notification until we have
1046 // completed the drag, only then do we want the image compositor notofied.
1047 // We therefore set the caller identity to the special case of 0
1048 mv->set_duration(new_dur_val, 0) ;
1051 show_verbose_time_cursor(new_dur_val, 10) ;
1056 Editor::markerview_end_handle_end_trim (ArdourCanvas::Item* item, GdkEvent* event)
1058 MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
1060 if (drag_info.cumulative_x_drag == 0)
1066 nframes_t new_duration = (nframes_t)drag_info.cumulative_x_drag ;
1067 mv->set_duration(new_duration, this) ;
1072 /* </CMT Additions file="editor_mouse.cc"> */
1080 /* <CMT Additions file="editor_route_list.cc"> */
1083 Editor::handle_new_imageframe_time_axis_view(const string & track_name, void* src)
1085 ImageFrameTimeAxis* iftav ;
1086 iftav = new ImageFrameTimeAxis(track_name, *this, *session, track_canvas) ;
1087 iftav->set_time_axis_name(track_name, this) ;
1088 track_views.push_back(iftav) ;
1090 TreeModel::Row row = *(route_display_model->append());
1092 row[route_display_columns.text] = iftav->name();
1093 row[route_display_columns.tv] = iftav;
1094 route_list_display.get_selection()->select (row);
1096 iftav->GoingAway.connect(bind(mem_fun(*this, &Editor::remove_route), (TimeAxisView*)iftav)) ;
1097 iftav->gui_changed.connect(mem_fun(*this, &Editor::handle_gui_changes)) ;
1101 Editor::handle_new_imageframe_marker_time_axis_view(const string & track_name, TimeAxisView* marked_track)
1103 MarkerTimeAxis* mta = new MarkerTimeAxis (*this, *this->current_session(), track_canvas, track_name, marked_track) ;
1104 ((ImageFrameTimeAxis*)marked_track)->add_marker_time_axis(mta, this) ;
1105 track_views.push_back(mta) ;
1107 TreeModel::Row row = *(route_display_model->append());
1109 row[route_display_columns.text] = mta->name();
1110 row[route_display_columns.tv] = mta;
1111 route_list_display.get_selection()->select (row);
1113 mta->GoingAway.connect(bind(mem_fun(*this, &Editor::remove_route), (TimeAxisView*)mta)) ;
1117 /* </CMT Additions file="editor_route_list.cc"> */