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"
44 #include "gui_thread.h"
51 Editor::get_named_time_axis(const string & name)
53 TimeAxisView* tav = 0 ;
55 for (TrackViewList::const_iterator i = track_views.begin(); i != track_views.end(); ++i)
57 if (((TimeAxisView*)*i)->name() == name)
59 tav = ((TimeAxisView*)*i) ;
66 /* <CMT Additions file="editor.cc"> */
69 Editor::add_imageframe_time_axis(const string & track_name, void* src)
71 // check for duplicate name
72 if(get_named_time_axis(track_name))
74 warning << "Repeated time axis name" << std::endl ;
78 Gtkmm2ext::UI::instance()->call_slot (boost::bind (&Editor::handle_new_imageframe_time_axis_view, this,track_name, src));
83 Editor::connect_to_image_compositor()
85 if(image_socket_listener == 0)
87 image_socket_listener = ImageFrameSocketHandler::create_instance(*this) ;
90 if(image_socket_listener->is_connected() == true)
95 // XXX should really put this somewhere safe
96 const char * host_ip = "127.0.0.1" ;
98 bool retcode = image_socket_listener->connect(host_ip, ardourvis::DEFAULT_PORT) ;
102 // XXX need to get some return status here
103 warning << "Image Compositor Connection attempt failed" << std::endl ;
107 // add the socket to the gui loop, and keep the retuned tag value of the input
108 gint tag = gdk_input_add(image_socket_listener->get_socket_descriptor(), GDK_INPUT_READ,ImageFrameSocketHandler::image_socket_callback,image_socket_listener) ;
109 image_socket_listener->set_gdk_input_tag(tag) ;
113 Editor::scroll_timeaxis_to_imageframe_item(const TimeAxisViewItem* item)
116 //framepos_t offset = static_cast<framepos_t>(frames_per_unit * (edit_hscroll_slider_width/2)) ;
117 framepos_t offset = 0;
119 framepos_t x_pos = 0 ;
121 if (item->get_position() < offset) {
124 x_pos = item->get_position() - offset + (item->get_duration() / 2);
127 reset_x_origin (x_pos);
131 Editor::add_imageframe_marker_time_axis(const string & track_name, TimeAxisView* marked_track, void* src)
133 // Can we only sigc::bind 2 data Items?
134 // @todo we really want to sigc::bind the src attribute too, for the moment tracks can only be added remotely,
135 // so this is not too much of an issue, however will need to be looked at again
136 Gtkmm2ext::UI::instance()->call_slot (boost::bind (&Editor::handle_new_imageframe_marker_time_axis_view, this, track_name, marked_track));
140 Editor::popup_imageframe_edit_menu(int button, int32_t time, ArdourCanvas::Item* ifv, bool with_item)
142 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(clicked_axisview) ;
146 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_selected_imageframe_group() ;
150 ImageFrameView* selected_ifv = ifta->get_view()->get_selected_imageframe_view() ;
151 ifta->popup_imageframe_edit_menu(button, time, selected_ifv, with_item) ;
157 Editor::popup_marker_time_axis_edit_menu(int button, int32_t time, ArdourCanvas::Item* ifv, bool with_item)
159 MarkerTimeAxis* mta = dynamic_cast<MarkerTimeAxis*>(clicked_axisview) ;
163 MarkerView* selected_mv = mta->get_view()->get_selected_time_axis_item() ;
166 mta->popup_marker_time_axis_edit_menu(button,time, selected_mv, with_item) ;
170 /* </CMT Additions file="editor.cc"> */
172 /* <CMT Additions file="editor_canvas_events.cc"> */
174 Editor::canvas_imageframe_item_view_event (GdkEvent *event, ArdourCanvas::Item* item, ImageFrameView *ifv)
177 ImageFrameTimeAxisGroup* iftag = 0 ;
181 case GDK_BUTTON_PRESS:
182 case GDK_2BUTTON_PRESS:
183 case GDK_3BUTTON_PRESS:
184 clicked_axisview = &ifv->get_time_axis_view();
185 iftag = ifv->get_time_axis_group() ;
186 dynamic_cast<ImageFrameTimeAxis*>(clicked_axisview)->get_view()->set_selected_imageframe_view(iftag, ifv);
187 ret = button_press_handler (item, event, ImageFrameItem) ;
189 case GDK_BUTTON_RELEASE:
190 ret = button_release_handler (item, event, ImageFrameItem) ;
192 case GDK_MOTION_NOTIFY:
193 ret = motion_handler (item, event, ImageFrameItem) ;
202 Editor::canvas_imageframe_start_handle_event (GdkEvent *event, ArdourCanvas::Item* item, ImageFrameView *ifv)
205 ImageFrameTimeAxisGroup* iftag = 0 ;
209 case GDK_BUTTON_PRESS:
210 case GDK_2BUTTON_PRESS:
211 case GDK_3BUTTON_PRESS:
212 clicked_axisview = &ifv->get_time_axis_view() ;
213 iftag = ifv->get_time_axis_group() ;
214 dynamic_cast<ImageFrameTimeAxis*>(clicked_axisview)->get_view()->set_selected_imageframe_view(iftag, ifv);
216 ret = button_press_handler (item, event, ImageFrameHandleStartItem) ;
218 case GDK_BUTTON_RELEASE:
219 ret = button_release_handler (item, event, ImageFrameHandleStartItem) ;
221 case GDK_MOTION_NOTIFY:
222 ret = motion_handler (item, event, ImageFrameHandleStartItem) ;
224 case GDK_ENTER_NOTIFY:
225 ret = enter_handler (item, event, ImageFrameHandleStartItem) ;
227 case GDK_LEAVE_NOTIFY:
228 ret = leave_handler (item, event, ImageFrameHandleStartItem) ;
237 Editor::canvas_imageframe_end_handle_event (GdkEvent *event, ArdourCanvas::Item* item, ImageFrameView *ifv)
240 ImageFrameTimeAxisGroup* iftag = 0 ;
244 case GDK_BUTTON_PRESS:
245 case GDK_2BUTTON_PRESS:
246 case GDK_3BUTTON_PRESS:
247 clicked_axisview = &ifv->get_time_axis_view() ;
248 iftag = ifv->get_time_axis_group() ;
249 dynamic_cast<ImageFrameTimeAxis*>(clicked_axisview)->get_view()->set_selected_imageframe_view(iftag, ifv);
251 ret = button_press_handler (item, event, ImageFrameHandleEndItem) ;
253 case GDK_BUTTON_RELEASE:
254 ret = button_release_handler (item, event, ImageFrameHandleEndItem) ;
256 case GDK_MOTION_NOTIFY:
257 ret = motion_handler (item, event, ImageFrameHandleEndItem) ;
259 case GDK_ENTER_NOTIFY:
260 ret = enter_handler (item, event, ImageFrameHandleEndItem) ;
262 case GDK_LEAVE_NOTIFY:
263 ret = leave_handler (item, event, ImageFrameHandleEndItem);
272 Editor::canvas_imageframe_view_event (GdkEvent* event, ArdourCanvas::Item* item, ImageFrameTimeAxis* ifta)
277 case GDK_BUTTON_PRESS:
278 case GDK_2BUTTON_PRESS:
279 case GDK_3BUTTON_PRESS:
280 clicked_axisview = ifta ;
281 ret = button_press_handler (item, event, ImageFrameTimeAxisItem) ;
283 case GDK_BUTTON_RELEASE:
284 ret = button_release_handler (item, event, ImageFrameTimeAxisItem) ;
286 case GDK_MOTION_NOTIFY:
295 Editor::canvas_marker_time_axis_view_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerTimeAxis* mta)
300 case GDK_BUTTON_PRESS:
301 case GDK_2BUTTON_PRESS:
302 case GDK_3BUTTON_PRESS:
303 clicked_axisview = mta ;
304 ret = button_press_handler(item, event, MarkerTimeAxisItem) ;
306 case GDK_BUTTON_RELEASE:
307 ret = button_release_handler(item, event, MarkerTimeAxisItem) ;
309 case GDK_MOTION_NOTIFY:
318 Editor::canvas_markerview_item_view_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerView* mta)
323 case GDK_BUTTON_PRESS:
324 case GDK_2BUTTON_PRESS:
325 case GDK_3BUTTON_PRESS:
326 clicked_axisview = &mta->get_time_axis_view() ;
327 dynamic_cast<MarkerTimeAxis*>(clicked_axisview)->get_view()->set_selected_time_axis_item(mta);
328 ret = button_press_handler(item, event, MarkerViewItem) ;
330 case GDK_BUTTON_RELEASE:
331 ret = button_release_handler(item, event, MarkerViewItem) ;
333 case GDK_MOTION_NOTIFY:
334 ret = motion_handler(item, event, MarkerViewItem) ;
343 Editor::canvas_markerview_start_handle_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerView* mta)
348 case GDK_BUTTON_PRESS:
349 case GDK_2BUTTON_PRESS:
350 case GDK_3BUTTON_PRESS:
351 clicked_axisview = &mta->get_time_axis_view() ;
352 dynamic_cast<MarkerTimeAxis*>(clicked_axisview)->get_view()->set_selected_time_axis_item(mta) ;
353 ret = button_press_handler(item, event, MarkerViewHandleStartItem) ;
355 case GDK_BUTTON_RELEASE:
356 ret = button_release_handler(item, event, MarkerViewHandleStartItem) ;
358 case GDK_MOTION_NOTIFY:
359 ret = motion_handler(item, event, MarkerViewHandleStartItem) ;
361 case GDK_ENTER_NOTIFY:
362 ret = enter_handler(item, event, MarkerViewHandleStartItem) ;
364 case GDK_LEAVE_NOTIFY:
365 ret = leave_handler(item, event, MarkerViewHandleStartItem) ;
374 Editor::canvas_markerview_end_handle_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerView* mta)
379 case GDK_BUTTON_PRESS:
380 case GDK_2BUTTON_PRESS:
381 case GDK_3BUTTON_PRESS:
382 clicked_axisview = &mta->get_time_axis_view() ;
383 dynamic_cast<MarkerTimeAxis*>(clicked_axisview)->get_view()->set_selected_time_axis_item(mta) ;
384 ret = button_press_handler(item, event, MarkerViewHandleEndItem) ;
386 case GDK_BUTTON_RELEASE:
387 ret = button_release_handler(item, event, MarkerViewHandleEndItem) ;
389 case GDK_MOTION_NOTIFY:
390 ret = motion_handler(item, event, MarkerViewHandleEndItem) ;
392 case GDK_ENTER_NOTIFY:
393 ret = enter_handler(item, event, MarkerViewHandleEndItem) ;
395 case GDK_LEAVE_NOTIFY:
396 ret = leave_handler(item, event, MarkerViewHandleEndItem) ;
405 /* </CMT Additions file="editor_canvas_events.cc"> */
409 ---------------------------------------------------------------------------------------------------
410 ---------------------------------------------------------------------------------------------------
411 ---------------------------------------------------------------------------------------------------
416 /* <CMT Additions file="editor_mouse.cc"> */
419 Editor::start_imageframe_grab(ArdourCanvas::Item* item, GdkEvent* event)
421 ImageFrameView* ifv = ((ImageFrameTimeAxis*)clicked_axisview)->get_view()->get_selected_imageframe_view() ;
422 drag_info.copy = false ;
423 drag_info.item = item ;
424 drag_info.data = ifv ;
425 drag_info.motion_callback = &Editor::imageframe_drag_motion_callback;
426 drag_info.finished_callback = &Editor::timeaxis_item_drag_finished_callback;
427 drag_info.last_frame_position = ifv->get_position() ;
429 drag_info.source_trackview = &ifv->get_time_axis_view() ;
430 drag_info.dest_trackview = drag_info.source_trackview;
432 /* this is subtle. raising the regionview itself won't help,
433 because raise_to_top() just puts the item on the top of
434 its parent's stack. so, we need to put the trackview canvas_display group
435 on the top, since its parent is the whole canvas.
437 however, this hides the measure bars within that particular trackview,
438 so move them to the top afterwards.
441 drag_info.item->raise_to_top();
442 drag_info.source_trackview->canvas_display->raise_to_top();
443 //time_line_group->raise_to_top();
444 cursor_group->raise_to_top ();
448 drag_info.pointer_frame_offset = pixel_to_frame(drag_info.grab_x) - drag_info.last_frame_position;
453 Editor::start_markerview_grab(ArdourCanvas::Item* item, GdkEvent* event)
455 MarkerView* mv = ((MarkerTimeAxis*)clicked_axisview)->get_view()->get_selected_time_axis_item() ;
456 drag_info.copy = false ;
457 drag_info.item = item ;
458 drag_info.data = mv ;
459 drag_info.motion_callback = &Editor::markerview_drag_motion_callback;
460 drag_info.finished_callback = &Editor::timeaxis_item_drag_finished_callback;
461 drag_info.last_frame_position = mv->get_position() ;
463 drag_info.source_trackview = &mv->get_time_axis_view() ;
464 drag_info.dest_trackview = drag_info.source_trackview;
466 /* this is subtle. raising the regionview itself won't help,
467 because raise_to_top() just puts the item on the top of
468 its parent's stack. so, we need to put the trackview canvas_display group
469 on the top, since its parent is the whole canvas.
471 however, this hides the measure bars within that particular trackview,
472 so move them to the top afterwards.
475 drag_info.item->raise_to_top();
476 drag_info.source_trackview->canvas_display->raise_to_top();
477 //time_line_group->raise_to_top();
478 cursor_group->raise_to_top ();
482 drag_info.pointer_frame_offset = pixel_to_frame(drag_info.grab_x) - drag_info.last_frame_position ;
487 Editor::markerview_drag_motion_callback(ArdourCanvas::Item*, GdkEvent* event)
491 MarkerView* mv = reinterpret_cast<MarkerView*>(drag_info.data) ;
492 framepos_t pending_region_position ;
493 framepos_t pointer_frame ;
495 pointer_frame = event_frame(event, &cx, &cy) ;
497 snap_to(pointer_frame) ;
499 if (pointer_frame > (framepos_t) drag_info.pointer_frame_offset)
501 pending_region_position = pointer_frame - drag_info.pointer_frame_offset ;
502 snap_to(pending_region_position) ;
504 // we dont allow marker items to extend beyond, or in front of the marked items so
505 // cap the value to the marked items position and duration
506 if((pending_region_position + mv->get_duration()) >= ((mv->get_marked_item()->get_position()) + (mv->get_marked_item()->get_duration())))
508 pending_region_position = (mv->get_marked_item()->get_position() + mv->get_marked_item()->get_duration()) - (mv->get_duration()) ;
510 else if(pending_region_position <= mv->get_marked_item()->get_position())
512 pending_region_position = mv->get_marked_item()->get_position() ;
517 pending_region_position = mv->get_marked_item()->get_position() ;
520 drag_info.last_frame_position = pending_region_position ;
522 // we treat this as a special case, usually we want to send the identitiy of the caller
523 // but in this case, that would trigger our socket handler to handle the event, sending
524 // notification to the image compositor. This would be fine, except that we have not
525 // finished the drag, we therefore do not want to sent notification until we have
526 // completed the drag, only then do we want the image compositor notofied.
527 // We therefore set the caller identity to the special case of 0
528 mv->set_position(pending_region_position, 0) ;
530 show_verbose_time_cursor(pending_region_position) ;
534 Editor::imageframe_drag_motion_callback(ArdourCanvas::Item*, GdkEvent* event)
538 ImageFrameView* ifv = reinterpret_cast<ImageFrameView*>(drag_info.data) ;
540 framepos_t pending_region_position;
541 framepos_t pointer_frame;
543 pointer_frame = event_frame(event, &cx, &cy) ;
545 snap_to(pointer_frame) ;
547 if (pointer_frame > (framepos_t) drag_info.pointer_frame_offset)
549 pending_region_position = pointer_frame - drag_info.pointer_frame_offset ;
550 snap_to(pending_region_position) ;
554 pending_region_position = 0 ;
557 drag_info.grab_x = cx;
558 //drag_info.last_frame_position = pending_region_position ;
559 drag_info.current_pointer_frame = pending_region_position ;
561 // we treat this as a special case, usually we want to send the identitiy of the caller
562 // but in this case, that would trigger our socket handler to handle the event, sending
563 // notification to the image compositor. This would be fine, except that we have not
564 // finished the drag, we therefore do not want to sent notification until we have
565 // completed the drag, only then do we want the image compositor notofied.
566 // We therefore set the caller identity to the special case of 0
567 ifv->set_position(pending_region_position, 0) ;
569 show_verbose_time_cursor(pending_region_position) ;
573 Editor::timeaxis_item_drag_finished_callback(ArdourCanvas::Item*, GdkEvent* event)
576 TimeAxisViewItem* tavi = reinterpret_cast<TimeAxisViewItem*>(drag_info.data) ;
578 bool item_x_movement = (drag_info.last_frame_position != tavi->get_position()) ;
580 hide_verbose_canvas_cursor() ;
582 /* no x or y movement either means the regionview hasn't been moved, or has been moved
583 but is back in it's original position/trackview.*/
585 if(!item_x_movement && event && event->type == GDK_BUTTON_RELEASE)
587 /* No motion: either set the current region, or align the clicked region
588 with the current one.
595 /* base the new region position on the current position of the regionview.*/
596 where = drag_info.current_pointer_frame ;
598 // final call to set position after the motion to tell interested parties of the new position
599 tavi->set_position(where, this) ;
603 //where = tavi->get_position() ;
607 //locate so user can audition the edit
608 if ( !session->transport_rolling() && Config->get_always_play_range()) {
609 locate_with_edit_preroll ( arv->region()->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_axisview) ;
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_axisview) ;
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 framepos_t start = 0 ;
680 framepos_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 framepos_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 framepos_t temp = ifv->get_position() + ifv->get_duration() ;
757 ifv->set_position((framepos_t) (temp - drag_info.cumulative_x_drag), this) ;
758 ifv->set_duration((framepos_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 framepos_t start = 0 ;
769 framepos_t pointer_frame = event_frame(event) ;
770 framepos_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 framepos_t new_duration = (framepos_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_axisview)->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_axisview)->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 framepos_t start = 0 ;
894 framepos_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 framepos_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 framepos_t temp = mv->get_position() + mv->get_duration() ;
974 mv->set_position((framepos_t) (temp - drag_info.cumulative_x_drag), this) ;
975 mv->set_duration((framepos_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 framepos_t start = 0 ;
986 framepos_t pointer_frame = event_frame(event) ;
987 framepos_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 framepos_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 framepos_t new_duration = (framepos_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->gui_changed.connect(sigc::mem_fun(*this, &Editor::handle_gui_changes)) ;
1100 Editor::handle_new_imageframe_marker_time_axis_view(const string & track_name, TimeAxisView* marked_track)
1102 MarkerTimeAxis* mta = new MarkerTimeAxis (*this, *this->session(), *track_canvas, track_name, marked_track) ;
1103 ((ImageFrameTimeAxis*)marked_track)->add_marker_time_axis(mta, this) ;
1104 track_views.push_back(mta) ;
1106 TreeModel::Row row = *(route_display_model->append());
1108 row[route_display_columns.text] = mta->name();
1109 row[route_display_columns.tv] = mta;
1110 route_list_display.get_selection()->select (row);
1114 /* </CMT Additions file="editor_route_list.cc"> */