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 ;
104 if (item->get_position() < offset) {
107 x_pos = item->get_position() - offset + (item->get_duration() / 2);
110 reset_x_origin (x_pos);
114 Editor::add_imageframe_marker_time_axis(const string & track_name, TimeAxisView* marked_track, void* src)
116 // Can we only bind 2 data Items?
117 // @todo we really want to bind the src attribute too, for the moment tracks can only be added remotely,
118 // so this is not too much of an issue, however will need to be looked at again
119 Gtkmm2ext::UI::instance()->call_slot(sigc::bind(mem_fun(*this, &Editor::handle_new_imageframe_marker_time_axis_view),track_name, marked_track)) ;
123 Editor::popup_imageframe_edit_menu(int button, int32_t time, ArdourCanvas::Item* ifv, bool with_item)
125 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(clicked_axisview) ;
129 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_selected_imageframe_group() ;
133 ImageFrameView* selected_ifv = ifta->get_view()->get_selected_imageframe_view() ;
134 ifta->popup_imageframe_edit_menu(button, time, selected_ifv, with_item) ;
140 Editor::popup_marker_time_axis_edit_menu(int button, int32_t time, ArdourCanvas::Item* ifv, bool with_item)
142 MarkerTimeAxis* mta = dynamic_cast<MarkerTimeAxis*>(clicked_axisview) ;
146 MarkerView* selected_mv = mta->get_view()->get_selected_time_axis_item() ;
149 mta->popup_marker_time_axis_edit_menu(button,time, selected_mv, with_item) ;
155 Editor::get_named_time_axis(const string & name)
157 TimeAxisView* tav = 0 ;
159 for (TrackViewList::const_iterator i = track_views.begin(); i != track_views.end(); ++i)
161 if (((TimeAxisView*)*i)->name() == name)
163 tav = ((TimeAxisView*)*i) ;
170 /* </CMT Additions file="editor.cc"> */
177 /* <CMT Additions file="editor_canvas_events.cc"> */
179 Editor::canvas_imageframe_item_view_event (GdkEvent *event, ArdourCanvas::Item* item, ImageFrameView *ifv)
182 ImageFrameTimeAxisGroup* iftag = 0 ;
186 case GDK_BUTTON_PRESS:
187 case GDK_2BUTTON_PRESS:
188 case GDK_3BUTTON_PRESS:
189 clicked_axisview = &ifv->get_time_axis_view();
190 iftag = ifv->get_time_axis_group() ;
191 dynamic_cast<ImageFrameTimeAxis*>(clicked_axisview)->get_view()->set_selected_imageframe_view(iftag, ifv);
192 ret = button_press_handler (item, event, ImageFrameItem) ;
194 case GDK_BUTTON_RELEASE:
195 ret = button_release_handler (item, event, ImageFrameItem) ;
197 case GDK_MOTION_NOTIFY:
198 ret = motion_handler (item, event, ImageFrameItem) ;
207 Editor::canvas_imageframe_start_handle_event (GdkEvent *event, ArdourCanvas::Item* item, ImageFrameView *ifv)
210 ImageFrameTimeAxisGroup* iftag = 0 ;
214 case GDK_BUTTON_PRESS:
215 case GDK_2BUTTON_PRESS:
216 case GDK_3BUTTON_PRESS:
217 clicked_axisview = &ifv->get_time_axis_view() ;
218 iftag = ifv->get_time_axis_group() ;
219 dynamic_cast<ImageFrameTimeAxis*>(clicked_axisview)->get_view()->set_selected_imageframe_view(iftag, ifv);
221 ret = button_press_handler (item, event, ImageFrameHandleStartItem) ;
223 case GDK_BUTTON_RELEASE:
224 ret = button_release_handler (item, event, ImageFrameHandleStartItem) ;
226 case GDK_MOTION_NOTIFY:
227 ret = motion_handler (item, event, ImageFrameHandleStartItem) ;
229 case GDK_ENTER_NOTIFY:
230 ret = enter_handler (item, event, ImageFrameHandleStartItem) ;
232 case GDK_LEAVE_NOTIFY:
233 ret = leave_handler (item, event, ImageFrameHandleStartItem) ;
242 Editor::canvas_imageframe_end_handle_event (GdkEvent *event, ArdourCanvas::Item* item, ImageFrameView *ifv)
245 ImageFrameTimeAxisGroup* iftag = 0 ;
249 case GDK_BUTTON_PRESS:
250 case GDK_2BUTTON_PRESS:
251 case GDK_3BUTTON_PRESS:
252 clicked_axisview = &ifv->get_time_axis_view() ;
253 iftag = ifv->get_time_axis_group() ;
254 dynamic_cast<ImageFrameTimeAxis*>(clicked_axisview)->get_view()->set_selected_imageframe_view(iftag, ifv);
256 ret = button_press_handler (item, event, ImageFrameHandleEndItem) ;
258 case GDK_BUTTON_RELEASE:
259 ret = button_release_handler (item, event, ImageFrameHandleEndItem) ;
261 case GDK_MOTION_NOTIFY:
262 ret = motion_handler (item, event, ImageFrameHandleEndItem) ;
264 case GDK_ENTER_NOTIFY:
265 ret = enter_handler (item, event, ImageFrameHandleEndItem) ;
267 case GDK_LEAVE_NOTIFY:
268 ret = leave_handler (item, event, ImageFrameHandleEndItem);
277 Editor::canvas_imageframe_view_event (GdkEvent* event, ArdourCanvas::Item* item, ImageFrameTimeAxis* ifta)
282 case GDK_BUTTON_PRESS:
283 case GDK_2BUTTON_PRESS:
284 case GDK_3BUTTON_PRESS:
285 clicked_axisview = ifta ;
286 ret = button_press_handler (item, event, ImageFrameTimeAxisItem) ;
288 case GDK_BUTTON_RELEASE:
289 ret = button_release_handler (item, event, ImageFrameTimeAxisItem) ;
291 case GDK_MOTION_NOTIFY:
300 Editor::canvas_marker_time_axis_view_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerTimeAxis* mta)
305 case GDK_BUTTON_PRESS:
306 case GDK_2BUTTON_PRESS:
307 case GDK_3BUTTON_PRESS:
308 clicked_axisview = mta ;
309 ret = button_press_handler(item, event, MarkerTimeAxisItem) ;
311 case GDK_BUTTON_RELEASE:
312 ret = button_release_handler(item, event, MarkerTimeAxisItem) ;
314 case GDK_MOTION_NOTIFY:
323 Editor::canvas_markerview_item_view_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerView* mta)
328 case GDK_BUTTON_PRESS:
329 case GDK_2BUTTON_PRESS:
330 case GDK_3BUTTON_PRESS:
331 clicked_axisview = &mta->get_time_axis_view() ;
332 dynamic_cast<MarkerTimeAxis*>(clicked_axisview)->get_view()->set_selected_time_axis_item(mta);
333 ret = button_press_handler(item, event, MarkerViewItem) ;
335 case GDK_BUTTON_RELEASE:
336 ret = button_release_handler(item, event, MarkerViewItem) ;
338 case GDK_MOTION_NOTIFY:
339 ret = motion_handler(item, event, MarkerViewItem) ;
348 Editor::canvas_markerview_start_handle_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerView* mta)
353 case GDK_BUTTON_PRESS:
354 case GDK_2BUTTON_PRESS:
355 case GDK_3BUTTON_PRESS:
356 clicked_axisview = &mta->get_time_axis_view() ;
357 dynamic_cast<MarkerTimeAxis*>(clicked_axisview)->get_view()->set_selected_time_axis_item(mta) ;
358 ret = button_press_handler(item, event, MarkerViewHandleStartItem) ;
360 case GDK_BUTTON_RELEASE:
361 ret = button_release_handler(item, event, MarkerViewHandleStartItem) ;
363 case GDK_MOTION_NOTIFY:
364 ret = motion_handler(item, event, MarkerViewHandleStartItem) ;
366 case GDK_ENTER_NOTIFY:
367 ret = enter_handler(item, event, MarkerViewHandleStartItem) ;
369 case GDK_LEAVE_NOTIFY:
370 ret = leave_handler(item, event, MarkerViewHandleStartItem) ;
379 Editor::canvas_markerview_end_handle_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerView* mta)
384 case GDK_BUTTON_PRESS:
385 case GDK_2BUTTON_PRESS:
386 case GDK_3BUTTON_PRESS:
387 clicked_axisview = &mta->get_time_axis_view() ;
388 dynamic_cast<MarkerTimeAxis*>(clicked_axisview)->get_view()->set_selected_time_axis_item(mta) ;
389 ret = button_press_handler(item, event, MarkerViewHandleEndItem) ;
391 case GDK_BUTTON_RELEASE:
392 ret = button_release_handler(item, event, MarkerViewHandleEndItem) ;
394 case GDK_MOTION_NOTIFY:
395 ret = motion_handler(item, event, MarkerViewHandleEndItem) ;
397 case GDK_ENTER_NOTIFY:
398 ret = enter_handler(item, event, MarkerViewHandleEndItem) ;
400 case GDK_LEAVE_NOTIFY:
401 ret = leave_handler(item, event, MarkerViewHandleEndItem) ;
410 /* </CMT Additions file="editor_canvas_events.cc"> */
414 ---------------------------------------------------------------------------------------------------
415 ---------------------------------------------------------------------------------------------------
416 ---------------------------------------------------------------------------------------------------
421 /* <CMT Additions file="editor_mouse.cc"> */
424 Editor::start_imageframe_grab(ArdourCanvas::Item* item, GdkEvent* event)
426 ImageFrameView* ifv = ((ImageFrameTimeAxis*)clicked_axisview)->get_view()->get_selected_imageframe_view() ;
427 drag_info.copy = false ;
428 drag_info.item = item ;
429 drag_info.data = ifv ;
430 drag_info.motion_callback = &Editor::imageframe_drag_motion_callback;
431 drag_info.finished_callback = &Editor::timeaxis_item_drag_finished_callback;
432 drag_info.last_frame_position = ifv->get_position() ;
434 drag_info.last_trackview = &ifv->get_time_axis_view() ;
436 /* this is subtle. raising the regionview itself won't help,
437 because raise_to_top() just puts the item on the top of
438 its parent's stack. so, we need to put the trackview canvas_display group
439 on the top, since its parent is the whole canvas.
441 however, this hides the measure bars within that particular trackview,
442 so move them to the top afterwards.
445 drag_info.item->raise_to_top();
446 drag_info.last_trackview->canvas_display->raise_to_top();
447 //time_line_group->raise_to_top();
448 cursor_group->raise_to_top ();
452 drag_info.pointer_frame_offset = pixel_to_frame(drag_info.grab_x) - drag_info.last_frame_position;
457 Editor::start_markerview_grab(ArdourCanvas::Item* item, GdkEvent* event)
459 MarkerView* mv = ((MarkerTimeAxis*)clicked_axisview)->get_view()->get_selected_time_axis_item() ;
460 drag_info.copy = false ;
461 drag_info.item = item ;
462 drag_info.data = mv ;
463 drag_info.motion_callback = &Editor::markerview_drag_motion_callback;
464 drag_info.finished_callback = &Editor::timeaxis_item_drag_finished_callback;
465 drag_info.last_frame_position = mv->get_position() ;
467 drag_info.last_trackview = &mv->get_time_axis_view() ;
469 /* this is subtle. raising the regionview itself won't help,
470 because raise_to_top() just puts the item on the top of
471 its parent's stack. so, we need to put the trackview canvas_display group
472 on the top, since its parent is the whole canvas.
474 however, this hides the measure bars within that particular trackview,
475 so move them to the top afterwards.
478 drag_info.item->raise_to_top();
479 drag_info.last_trackview->canvas_display->raise_to_top();
480 //time_line_group->raise_to_top();
481 cursor_group->raise_to_top ();
485 drag_info.pointer_frame_offset = pixel_to_frame(drag_info.grab_x) - drag_info.last_frame_position ;
490 Editor::markerview_drag_motion_callback(ArdourCanvas::Item*, GdkEvent* event)
494 MarkerView* mv = reinterpret_cast<MarkerView*>(drag_info.data) ;
495 nframes_t pending_region_position ;
496 nframes_t pointer_frame ;
498 pointer_frame = event_frame(event, &cx, &cy) ;
500 snap_to(pointer_frame) ;
502 if (pointer_frame > (nframes_t) drag_info.pointer_frame_offset)
504 pending_region_position = pointer_frame - drag_info.pointer_frame_offset ;
505 snap_to(pending_region_position) ;
507 // we dont allow marker items to extend beyond, or in front of the marked items so
508 // cap the value to the marked items position and duration
509 if((pending_region_position + mv->get_duration()) >= ((mv->get_marked_item()->get_position()) + (mv->get_marked_item()->get_duration())))
511 pending_region_position = (mv->get_marked_item()->get_position() + mv->get_marked_item()->get_duration()) - (mv->get_duration()) ;
513 else if(pending_region_position <= mv->get_marked_item()->get_position())
515 pending_region_position = mv->get_marked_item()->get_position() ;
520 pending_region_position = mv->get_marked_item()->get_position() ;
523 drag_info.last_frame_position = pending_region_position ;
525 // we treat this as a special case, usually we want to send the identitiy of the caller
526 // but in this case, that would trigger our socket handler to handle the event, sending
527 // notification to the image compositor. This would be fine, except that we have not
528 // finished the drag, we therefore do not want to sent notification until we have
529 // completed the drag, only then do we want the image compositor notofied.
530 // We therefore set the caller identity to the special case of 0
531 mv->set_position(pending_region_position, 0) ;
533 show_verbose_time_cursor(pending_region_position) ;
537 Editor::imageframe_drag_motion_callback(ArdourCanvas::Item*, GdkEvent* event)
541 ImageFrameView* ifv = reinterpret_cast<ImageFrameView*>(drag_info.data) ;
543 nframes_t pending_region_position;
544 nframes_t pointer_frame;
546 pointer_frame = event_frame(event, &cx, &cy) ;
548 snap_to(pointer_frame) ;
550 if (pointer_frame > (nframes_t) drag_info.pointer_frame_offset)
552 pending_region_position = pointer_frame - drag_info.pointer_frame_offset ;
553 snap_to(pending_region_position) ;
557 pending_region_position = 0 ;
560 drag_info.grab_x = cx;
561 //drag_info.last_frame_position = pending_region_position ;
562 drag_info.current_pointer_frame = pending_region_position ;
564 // we treat this as a special case, usually we want to send the identitiy of the caller
565 // but in this case, that would trigger our socket handler to handle the event, sending
566 // notification to the image compositor. This would be fine, except that we have not
567 // finished the drag, we therefore do not want to sent notification until we have
568 // completed the drag, only then do we want the image compositor notofied.
569 // We therefore set the caller identity to the special case of 0
570 ifv->set_position(pending_region_position, 0) ;
572 show_verbose_time_cursor(pending_region_position) ;
576 Editor::timeaxis_item_drag_finished_callback(ArdourCanvas::Item*, GdkEvent* event)
579 TimeAxisViewItem* tavi = reinterpret_cast<TimeAxisViewItem*>(drag_info.data) ;
581 bool item_x_movement = (drag_info.last_frame_position != tavi->get_position()) ;
583 hide_verbose_canvas_cursor() ;
585 /* no x or y movement either means the regionview hasn't been moved, or has been moved
586 but is back in it's original position/trackview.*/
588 if(!item_x_movement && event && event->type == GDK_BUTTON_RELEASE)
590 /* No motion: either set the current region, or align the clicked region
591 with the current one.
598 /* base the new region position on the current position of the regionview.*/
599 where = drag_info.current_pointer_frame ;
601 // final call to set position after the motion to tell interested parties of the new position
602 tavi->set_position(where, this) ;
606 //where = tavi->get_position() ;
614 Editor::imageframe_start_handle_op(ArdourCanvas::Item* item, GdkEvent* event)
616 // get the selected item from the parent time axis
617 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(clicked_axisview) ;
620 ImageFrameView* ifv = ifta->get_view()->get_selected_imageframe_view() ;
623 fatal << _("programming error: no ImageFrameView selected") << endmsg;
628 drag_info.item = ifv->get_canvas_frame() ;
629 drag_info.data = ifv;
630 drag_info.grab_x = event->motion.x;
631 drag_info.cumulative_x_drag = 0;
632 drag_info.motion_callback = &Editor::imageframe_start_handle_trim_motion ;
633 drag_info.finished_callback = &Editor::imageframe_start_handle_end_trim ;
637 show_verbose_time_cursor(ifv->get_position(), 10) ;
642 Editor::imageframe_end_handle_op(ArdourCanvas::Item* item, GdkEvent* event)
644 // get the selected item from the parent time axis
645 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(clicked_axisview) ;
649 ImageFrameView* ifv = ifta->get_view()->get_selected_imageframe_view() ;
653 fatal << _("programming error: no ImageFrameView selected") << endmsg ;
658 drag_info.item = ifv->get_canvas_frame() ;
659 drag_info.data = ifv ;
660 drag_info.grab_x = event->motion.x ;
661 drag_info.cumulative_x_drag = 0 ;
662 drag_info.motion_callback = &Editor::imageframe_end_handle_trim_motion ;
663 drag_info.finished_callback = &Editor::imageframe_end_handle_end_trim ;
665 start_grab(event, trimmer_cursor) ;
667 show_verbose_time_cursor(ifv->get_position() + ifv->get_duration(), 10) ;
672 Editor::imageframe_start_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* event)
674 ImageFrameView* ifv = reinterpret_cast<ImageFrameView*> (drag_info.data) ;
676 nframes_t start = 0 ;
678 nframes_t pointer_frame = event_frame(event) ;
680 // chekc th eposition of the item is not locked
681 if(!ifv->get_position_locked()) {
682 snap_to(pointer_frame) ;
684 if(pointer_frame != drag_info.last_pointer_frame) {
685 start = ifv->get_position() ;
686 end = ifv->get_position() + ifv->get_duration() ;
688 if (pointer_frame > end) {
691 start = pointer_frame ;
694 // are we getting bigger or smaller?
695 nframes_t new_dur_val = end - start ;
697 // start handle, so a smaller pointer frame increases our component size
698 if(pointer_frame <= drag_info.grab_frame)
700 if(ifv->get_max_duration_active() && (new_dur_val > ifv->get_max_duration()))
702 new_dur_val = ifv->get_max_duration() ;
703 start = end - new_dur_val ;
707 // current values are ok
712 if(ifv->get_min_duration_active() && (new_dur_val < ifv->get_min_duration()))
714 new_dur_val = ifv->get_min_duration() ;
715 start = end - new_dur_val ;
719 // current values are ok
723 drag_info.last_pointer_frame = pointer_frame ;
725 /* re-calculatethe duration and position of the imageframeview */
726 drag_info.cumulative_x_drag = new_dur_val ;
728 // we treat this as a special case, usually we want to send the identitiy of the caller
729 // but in this case, that would trigger our socket handler to handle the event, sending
730 // notification to the image compositor. This would be fine, except that we have not
731 // finished the drag, we therefore do not want to sent notification until we have
732 // completed the drag, only then do we want the image compositor notofied.
733 // We therefore set the caller identity to the special case of 0
734 ifv->set_duration(new_dur_val, 0) ;
735 ifv->set_position(start, 0) ;
739 show_verbose_time_cursor(start, 10) ;
743 Editor::imageframe_start_handle_end_trim(ArdourCanvas::Item* item, GdkEvent* event)
745 ImageFrameView* ifv = reinterpret_cast<ImageFrameView *> (drag_info.data) ;
747 if (drag_info.cumulative_x_drag == 0)
753 nframes_t temp = ifv->get_position() + ifv->get_duration() ;
755 ifv->set_position((nframes_t) (temp - drag_info.cumulative_x_drag), this) ;
756 ifv->set_duration((nframes_t) drag_info.cumulative_x_drag, this) ;
761 Editor::imageframe_end_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* event)
763 ImageFrameView* ifv = reinterpret_cast<ImageFrameView *> (drag_info.data) ;
765 nframes_t start = 0 ;
767 nframes_t pointer_frame = event_frame(event) ;
768 nframes_t new_dur_val = 0 ;
770 snap_to(pointer_frame) ;
772 if (pointer_frame != drag_info.last_pointer_frame)
774 start = ifv->get_position() ;
775 end = ifv->get_position() + ifv->get_duration() ;
776 if (pointer_frame < start)
782 end = pointer_frame ;
785 new_dur_val = end - start ;
787 // are we getting bigger or smaller?
788 if(pointer_frame >= drag_info.last_pointer_frame)
790 if(ifv->get_max_duration_active() && (new_dur_val > ifv->get_max_duration()))
792 new_dur_val = ifv->get_max_duration() ;
797 if(ifv->get_min_duration_active() && (new_dur_val < ifv->get_min_duration()))
799 new_dur_val = ifv->get_min_duration() ;
803 drag_info.last_pointer_frame = pointer_frame ;
804 drag_info.cumulative_x_drag = new_dur_val ;
806 // we treat this as a special case, usually we want to send the identitiy of the caller
807 // but in this case, that would trigger our socket handler to handle the event, sending
808 // notification to the image compositor. This would be fine, except that we have not
809 // finished the drag, we therefore do not want to sent notification until we have
810 // completed the drag, only then do we want the image compositor notofied.
811 // We therefore set the caller identity to the special case of 0
812 ifv->set_duration(new_dur_val, 0) ;
815 show_verbose_time_cursor(new_dur_val, 10) ;
820 Editor::imageframe_end_handle_end_trim (ArdourCanvas::Item* item, GdkEvent* event)
822 ImageFrameView* ifv = reinterpret_cast<ImageFrameView *> (drag_info.data) ;
824 if (drag_info.cumulative_x_drag == 0)
830 nframes_t new_duration = (nframes_t)drag_info.cumulative_x_drag ;
831 if((new_duration <= ifv->get_max_duration()) && (new_duration >= ifv->get_min_duration()))
833 ifv->set_duration(new_duration, this) ;
840 Editor::markerview_item_start_handle_op(ArdourCanvas::Item* item, GdkEvent* event)
842 MarkerView* mv = reinterpret_cast<MarkerTimeAxis*>(clicked_axisview)->get_view()->get_selected_time_axis_item() ;
846 fatal << _("programming error: no MarkerView selected") << endmsg ;
851 drag_info.item = mv->get_canvas_frame() ;
853 drag_info.grab_x = event->motion.x;
855 drag_info.cumulative_x_drag = 0 ;
856 drag_info.motion_callback = &Editor::markerview_start_handle_trim_motion ;
857 drag_info.finished_callback = &Editor::markerview_start_handle_end_trim ;
859 start_grab(event, trimmer_cursor) ;
863 Editor::markerview_item_end_handle_op(ArdourCanvas::Item* item, GdkEvent* event)
865 MarkerView* mv = reinterpret_cast<MarkerTimeAxis*>(clicked_axisview)->get_view()->get_selected_time_axis_item() ;
868 fatal << _("programming error: no MarkerView selected") << endmsg ;
873 drag_info.item = mv->get_canvas_frame() ;
874 drag_info.data = mv ;
875 drag_info.grab_x = event->motion.x ;
876 drag_info.cumulative_x_drag = 0 ;
878 drag_info.motion_callback = &Editor::markerview_end_handle_trim_motion ;
879 drag_info.finished_callback = &Editor::markerview_end_handle_end_trim ;
881 start_grab(event, trimmer_cursor) ;
886 Editor::markerview_start_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* event)
888 MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
890 nframes_t start = 0 ;
892 nframes_t pointer_frame = event_frame(event) ;
894 // chekc th eposition of the item is not locked
895 if(!mv->get_position_locked())
897 snap_to(pointer_frame) ;
898 if(pointer_frame != drag_info.last_pointer_frame)
900 start = mv->get_position() ;
901 end = mv->get_position() + mv->get_duration() ;
903 if (pointer_frame > end)
909 start = pointer_frame ;
912 // are we getting bigger or smaller?
913 nframes_t new_dur_val = end - start ;
915 if(pointer_frame <= drag_info.grab_frame)
917 if(mv->get_max_duration_active() && (new_dur_val > mv->get_max_duration()))
919 new_dur_val = mv->get_max_duration() ;
920 start = end - new_dur_val ;
924 // current values are ok
929 if(mv->get_min_duration_active() && (new_dur_val < mv->get_min_duration()))
931 new_dur_val = mv->get_min_duration() ;
932 start = end - new_dur_val ;
936 // current values are ok
940 drag_info.last_pointer_frame = pointer_frame ;
942 /* re-calculatethe duration and position of the imageframeview */
943 drag_info.cumulative_x_drag = new_dur_val ;
945 // we treat this as a special case, usually we want to send the identitiy of the caller
946 // but in this case, that would trigger our socket handler to handle the event, sending
947 // notification to the image compositor. This would be fine, except that we have not
948 // finished the drag, we therefore do not want to sent notification until we have
949 // completed the drag, only then do we want the image compositor notofied.
950 // We therefore set the caller identity to the special case of 0
951 mv->set_duration(new_dur_val, 0) ;
952 mv->set_position(start, 0) ;
956 show_verbose_time_cursor(start, 10) ;
960 Editor::markerview_start_handle_end_trim(ArdourCanvas::Item* item, GdkEvent* event)
962 MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
964 if (drag_info.cumulative_x_drag == 0)
970 nframes_t temp = mv->get_position() + mv->get_duration() ;
972 mv->set_position((nframes_t) (temp - drag_info.cumulative_x_drag), this) ;
973 mv->set_duration((nframes_t) drag_info.cumulative_x_drag, this) ;
978 Editor::markerview_end_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* event)
980 MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
982 nframes_t start = 0 ;
984 nframes_t pointer_frame = event_frame(event) ;
985 nframes_t new_dur_val = 0 ;
987 snap_to(pointer_frame) ;
989 if (pointer_frame != drag_info.last_pointer_frame)
991 start = mv->get_position() ;
992 end = mv->get_position() + mv->get_duration() ;
994 if(pointer_frame < start)
1000 end = pointer_frame ;
1003 new_dur_val = end - start ;
1005 // are we getting bigger or smaller?
1006 if(pointer_frame >= drag_info.last_pointer_frame)
1008 // we cant extend beyond the item we are marking
1009 ImageFrameView* marked_item = mv->get_marked_item() ;
1010 nframes_t marked_end = marked_item->get_position() + marked_item->get_duration() ;
1012 if(mv->get_max_duration_active() && (new_dur_val > mv->get_max_duration()))
1014 if((start + mv->get_max_duration()) > marked_end)
1016 new_dur_val = marked_end - start ;
1020 new_dur_val = mv->get_max_duration() ;
1023 else if(end > marked_end)
1025 new_dur_val = marked_end - start ;
1030 if(mv->get_min_duration_active() && (new_dur_val < mv->get_min_duration()))
1032 new_dur_val = mv->get_min_duration() ;
1037 drag_info.last_pointer_frame = pointer_frame ;
1038 drag_info.cumulative_x_drag = new_dur_val ;
1040 // we treat this as a special case, usually we want to send the identitiy of the caller
1041 // but in this case, that would trigger our socket handler to handle the event, sending
1042 // notification to the image compositor. This would be fine, except that we have not
1043 // finished the drag, we therefore do not want to sent notification until we have
1044 // completed the drag, only then do we want the image compositor notofied.
1045 // We therefore set the caller identity to the special case of 0
1046 mv->set_duration(new_dur_val, 0) ;
1049 show_verbose_time_cursor(new_dur_val, 10) ;
1054 Editor::markerview_end_handle_end_trim (ArdourCanvas::Item* item, GdkEvent* event)
1056 MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
1058 if (drag_info.cumulative_x_drag == 0)
1064 nframes_t new_duration = (nframes_t)drag_info.cumulative_x_drag ;
1065 mv->set_duration(new_duration, this) ;
1070 /* </CMT Additions file="editor_mouse.cc"> */
1078 /* <CMT Additions file="editor_route_list.cc"> */
1081 Editor::handle_new_imageframe_time_axis_view(const string & track_name, void* src)
1083 ImageFrameTimeAxis* iftav ;
1084 iftav = new ImageFrameTimeAxis(track_name, *this, *session, track_canvas) ;
1085 iftav->set_time_axis_name(track_name, this) ;
1086 track_views.push_back(iftav) ;
1088 TreeModel::Row row = *(route_display_model->append());
1090 row[route_display_columns.text] = iftav->name();
1091 row[route_display_columns.tv] = iftav;
1092 route_list_display.get_selection()->select (row);
1094 iftav->GoingAway.connect(bind(mem_fun(*this, &Editor::remove_route), (TimeAxisView*)iftav)) ;
1095 iftav->gui_changed.connect(mem_fun(*this, &Editor::handle_gui_changes)) ;
1099 Editor::handle_new_imageframe_marker_time_axis_view(const string & track_name, TimeAxisView* marked_track)
1101 MarkerTimeAxis* mta = new MarkerTimeAxis (*this, *this->current_session(), track_canvas, track_name, marked_track) ;
1102 ((ImageFrameTimeAxis*)marked_track)->add_marker_time_axis(mta, this) ;
1103 track_views.push_back(mta) ;
1105 TreeModel::Row row = *(route_display_model->append());
1107 row[route_display_columns.text] = mta->name();
1108 row[route_display_columns.tv] = mta;
1109 route_list_display.get_selection()->select (row);
1111 mta->GoingAway.connect(bind(mem_fun(*this, &Editor::remove_route), (TimeAxisView*)mta)) ;
1115 /* </CMT Additions file="editor_route_list.cc"> */