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 //nframes64_t offset = static_cast<nframes64_t>(frames_per_unit * (edit_hscroll_slider_width/2)) ;
117 nframes64_t offset
= 0;
119 nframes64_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 nframes64_t pending_region_position
;
493 nframes64_t pointer_frame
;
495 pointer_frame
= event_frame(event
, &cx
, &cy
) ;
497 snap_to(pointer_frame
) ;
499 if (pointer_frame
> (nframes64_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 nframes64_t pending_region_position
;
541 nframes64_t pointer_frame
;
543 pointer_frame
= event_frame(event
, &cx
, &cy
) ;
545 snap_to(pointer_frame
) ;
547 if (pointer_frame
> (nframes64_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() ;
611 Editor::imageframe_start_handle_op(ArdourCanvas::Item
* item
, GdkEvent
* event
)
613 // get the selected item from the parent time axis
614 ImageFrameTimeAxis
* ifta
= dynamic_cast<ImageFrameTimeAxis
*>(clicked_axisview
) ;
617 ImageFrameView
* ifv
= ifta
->get_view()->get_selected_imageframe_view() ;
620 fatal
<< _("programming error: no ImageFrameView selected") << endmsg
;
625 drag_info
.item
= ifv
->get_canvas_frame() ;
626 drag_info
.data
= ifv
;
627 drag_info
.grab_x
= event
->motion
.x
;
628 drag_info
.cumulative_x_drag
= 0;
629 drag_info
.motion_callback
= &Editor::imageframe_start_handle_trim_motion
;
630 drag_info
.finished_callback
= &Editor::imageframe_start_handle_end_trim
;
634 show_verbose_time_cursor(ifv
->get_position(), 10) ;
639 Editor::imageframe_end_handle_op(ArdourCanvas::Item
* item
, GdkEvent
* event
)
641 // get the selected item from the parent time axis
642 ImageFrameTimeAxis
* ifta
= dynamic_cast<ImageFrameTimeAxis
*>(clicked_axisview
) ;
646 ImageFrameView
* ifv
= ifta
->get_view()->get_selected_imageframe_view() ;
650 fatal
<< _("programming error: no ImageFrameView selected") << endmsg
;
655 drag_info
.item
= ifv
->get_canvas_frame() ;
656 drag_info
.data
= ifv
;
657 drag_info
.grab_x
= event
->motion
.x
;
658 drag_info
.cumulative_x_drag
= 0 ;
659 drag_info
.motion_callback
= &Editor::imageframe_end_handle_trim_motion
;
660 drag_info
.finished_callback
= &Editor::imageframe_end_handle_end_trim
;
662 start_grab(event
, trimmer_cursor
) ;
664 show_verbose_time_cursor(ifv
->get_position() + ifv
->get_duration(), 10) ;
669 Editor::imageframe_start_handle_trim_motion(ArdourCanvas::Item
* item
, GdkEvent
* event
)
671 ImageFrameView
* ifv
= reinterpret_cast<ImageFrameView
*> (drag_info
.data
) ;
673 nframes64_t start
= 0 ;
674 nframes64_t end
= 0 ;
675 nframes64_t pointer_frame
= event_frame(event
) ;
677 // chekc th eposition of the item is not locked
678 if(!ifv
->get_position_locked()) {
679 snap_to(pointer_frame
) ;
681 if(pointer_frame
!= drag_info
.last_pointer_frame
) {
682 start
= ifv
->get_position() ;
683 end
= ifv
->get_position() + ifv
->get_duration() ;
685 if (pointer_frame
> end
) {
688 start
= pointer_frame
;
691 // are we getting bigger or smaller?
692 nframes64_t new_dur_val
= end
- start
;
694 // start handle, so a smaller pointer frame increases our component size
695 if(pointer_frame
<= drag_info
.grab_frame
)
697 if(ifv
->get_max_duration_active() && (new_dur_val
> ifv
->get_max_duration()))
699 new_dur_val
= ifv
->get_max_duration() ;
700 start
= end
- new_dur_val
;
704 // current values are ok
709 if(ifv
->get_min_duration_active() && (new_dur_val
< ifv
->get_min_duration()))
711 new_dur_val
= ifv
->get_min_duration() ;
712 start
= end
- new_dur_val
;
716 // current values are ok
720 drag_info
.last_pointer_frame
= pointer_frame
;
722 /* re-calculatethe duration and position of the imageframeview */
723 drag_info
.cumulative_x_drag
= new_dur_val
;
725 // we treat this as a special case, usually we want to send the identitiy of the caller
726 // but in this case, that would trigger our socket handler to handle the event, sending
727 // notification to the image compositor. This would be fine, except that we have not
728 // finished the drag, we therefore do not want to sent notification until we have
729 // completed the drag, only then do we want the image compositor notofied.
730 // We therefore set the caller identity to the special case of 0
731 ifv
->set_duration(new_dur_val
, 0) ;
732 ifv
->set_position(start
, 0) ;
736 show_verbose_time_cursor(start
, 10) ;
740 Editor::imageframe_start_handle_end_trim(ArdourCanvas::Item
* item
, GdkEvent
* event
)
742 ImageFrameView
* ifv
= reinterpret_cast<ImageFrameView
*> (drag_info
.data
) ;
744 if (drag_info
.cumulative_x_drag
== 0)
750 nframes64_t temp
= ifv
->get_position() + ifv
->get_duration() ;
752 ifv
->set_position((nframes64_t
) (temp
- drag_info
.cumulative_x_drag
), this) ;
753 ifv
->set_duration((nframes64_t
) drag_info
.cumulative_x_drag
, this) ;
758 Editor::imageframe_end_handle_trim_motion(ArdourCanvas::Item
* item
, GdkEvent
* event
)
760 ImageFrameView
* ifv
= reinterpret_cast<ImageFrameView
*> (drag_info
.data
) ;
762 nframes64_t start
= 0 ;
763 nframes64_t end
= 0 ;
764 nframes64_t pointer_frame
= event_frame(event
) ;
765 nframes64_t new_dur_val
= 0 ;
767 snap_to(pointer_frame
) ;
769 if (pointer_frame
!= drag_info
.last_pointer_frame
)
771 start
= ifv
->get_position() ;
772 end
= ifv
->get_position() + ifv
->get_duration() ;
773 if (pointer_frame
< start
)
779 end
= pointer_frame
;
782 new_dur_val
= end
- start
;
784 // are we getting bigger or smaller?
785 if(pointer_frame
>= drag_info
.last_pointer_frame
)
787 if(ifv
->get_max_duration_active() && (new_dur_val
> ifv
->get_max_duration()))
789 new_dur_val
= ifv
->get_max_duration() ;
794 if(ifv
->get_min_duration_active() && (new_dur_val
< ifv
->get_min_duration()))
796 new_dur_val
= ifv
->get_min_duration() ;
800 drag_info
.last_pointer_frame
= pointer_frame
;
801 drag_info
.cumulative_x_drag
= new_dur_val
;
803 // we treat this as a special case, usually we want to send the identitiy of the caller
804 // but in this case, that would trigger our socket handler to handle the event, sending
805 // notification to the image compositor. This would be fine, except that we have not
806 // finished the drag, we therefore do not want to sent notification until we have
807 // completed the drag, only then do we want the image compositor notofied.
808 // We therefore set the caller identity to the special case of 0
809 ifv
->set_duration(new_dur_val
, 0) ;
812 show_verbose_time_cursor(new_dur_val
, 10) ;
817 Editor::imageframe_end_handle_end_trim (ArdourCanvas::Item
* item
, GdkEvent
* event
)
819 ImageFrameView
* ifv
= reinterpret_cast<ImageFrameView
*> (drag_info
.data
) ;
821 if (drag_info
.cumulative_x_drag
== 0)
827 nframes64_t new_duration
= (nframes64_t
)drag_info
.cumulative_x_drag
;
828 if((new_duration
<= ifv
->get_max_duration()) && (new_duration
>= ifv
->get_min_duration()))
830 ifv
->set_duration(new_duration
, this) ;
837 Editor::markerview_item_start_handle_op(ArdourCanvas::Item
* item
, GdkEvent
* event
)
839 MarkerView
* mv
= reinterpret_cast<MarkerTimeAxis
*>(clicked_axisview
)->get_view()->get_selected_time_axis_item() ;
843 fatal
<< _("programming error: no MarkerView selected") << endmsg
;
848 drag_info
.item
= mv
->get_canvas_frame() ;
850 drag_info
.grab_x
= event
->motion
.x
;
852 drag_info
.cumulative_x_drag
= 0 ;
853 drag_info
.motion_callback
= &Editor::markerview_start_handle_trim_motion
;
854 drag_info
.finished_callback
= &Editor::markerview_start_handle_end_trim
;
856 start_grab(event
, trimmer_cursor
) ;
860 Editor::markerview_item_end_handle_op(ArdourCanvas::Item
* item
, GdkEvent
* event
)
862 MarkerView
* mv
= reinterpret_cast<MarkerTimeAxis
*>(clicked_axisview
)->get_view()->get_selected_time_axis_item() ;
865 fatal
<< _("programming error: no MarkerView selected") << endmsg
;
870 drag_info
.item
= mv
->get_canvas_frame() ;
871 drag_info
.data
= mv
;
872 drag_info
.grab_x
= event
->motion
.x
;
873 drag_info
.cumulative_x_drag
= 0 ;
875 drag_info
.motion_callback
= &Editor::markerview_end_handle_trim_motion
;
876 drag_info
.finished_callback
= &Editor::markerview_end_handle_end_trim
;
878 start_grab(event
, trimmer_cursor
) ;
883 Editor::markerview_start_handle_trim_motion(ArdourCanvas::Item
* item
, GdkEvent
* event
)
885 MarkerView
* mv
= reinterpret_cast<MarkerView
*> (drag_info
.data
) ;
887 nframes64_t start
= 0 ;
888 nframes64_t end
= 0 ;
889 nframes64_t pointer_frame
= event_frame(event
) ;
891 // chekc th eposition of the item is not locked
892 if(!mv
->get_position_locked())
894 snap_to(pointer_frame
) ;
895 if(pointer_frame
!= drag_info
.last_pointer_frame
)
897 start
= mv
->get_position() ;
898 end
= mv
->get_position() + mv
->get_duration() ;
900 if (pointer_frame
> end
)
906 start
= pointer_frame
;
909 // are we getting bigger or smaller?
910 nframes64_t new_dur_val
= end
- start
;
912 if(pointer_frame
<= drag_info
.grab_frame
)
914 if(mv
->get_max_duration_active() && (new_dur_val
> mv
->get_max_duration()))
916 new_dur_val
= mv
->get_max_duration() ;
917 start
= end
- new_dur_val
;
921 // current values are ok
926 if(mv
->get_min_duration_active() && (new_dur_val
< mv
->get_min_duration()))
928 new_dur_val
= mv
->get_min_duration() ;
929 start
= end
- new_dur_val
;
933 // current values are ok
937 drag_info
.last_pointer_frame
= pointer_frame
;
939 /* re-calculatethe duration and position of the imageframeview */
940 drag_info
.cumulative_x_drag
= new_dur_val
;
942 // we treat this as a special case, usually we want to send the identitiy of the caller
943 // but in this case, that would trigger our socket handler to handle the event, sending
944 // notification to the image compositor. This would be fine, except that we have not
945 // finished the drag, we therefore do not want to sent notification until we have
946 // completed the drag, only then do we want the image compositor notofied.
947 // We therefore set the caller identity to the special case of 0
948 mv
->set_duration(new_dur_val
, 0) ;
949 mv
->set_position(start
, 0) ;
953 show_verbose_time_cursor(start
, 10) ;
957 Editor::markerview_start_handle_end_trim(ArdourCanvas::Item
* item
, GdkEvent
* event
)
959 MarkerView
* mv
= reinterpret_cast<MarkerView
*> (drag_info
.data
) ;
961 if (drag_info
.cumulative_x_drag
== 0)
967 nframes64_t temp
= mv
->get_position() + mv
->get_duration() ;
969 mv
->set_position((nframes64_t
) (temp
- drag_info
.cumulative_x_drag
), this) ;
970 mv
->set_duration((nframes64_t
) drag_info
.cumulative_x_drag
, this) ;
975 Editor::markerview_end_handle_trim_motion(ArdourCanvas::Item
* item
, GdkEvent
* event
)
977 MarkerView
* mv
= reinterpret_cast<MarkerView
*> (drag_info
.data
) ;
979 nframes64_t start
= 0 ;
980 nframes64_t end
= 0 ;
981 nframes64_t pointer_frame
= event_frame(event
) ;
982 nframes64_t new_dur_val
= 0 ;
984 snap_to(pointer_frame
) ;
986 if (pointer_frame
!= drag_info
.last_pointer_frame
)
988 start
= mv
->get_position() ;
989 end
= mv
->get_position() + mv
->get_duration() ;
991 if(pointer_frame
< start
)
997 end
= pointer_frame
;
1000 new_dur_val
= end
- start
;
1002 // are we getting bigger or smaller?
1003 if(pointer_frame
>= drag_info
.last_pointer_frame
)
1005 // we cant extend beyond the item we are marking
1006 ImageFrameView
* marked_item
= mv
->get_marked_item() ;
1007 nframes64_t marked_end
= marked_item
->get_position() + marked_item
->get_duration() ;
1009 if(mv
->get_max_duration_active() && (new_dur_val
> mv
->get_max_duration()))
1011 if((start
+ mv
->get_max_duration()) > marked_end
)
1013 new_dur_val
= marked_end
- start
;
1017 new_dur_val
= mv
->get_max_duration() ;
1020 else if(end
> marked_end
)
1022 new_dur_val
= marked_end
- start
;
1027 if(mv
->get_min_duration_active() && (new_dur_val
< mv
->get_min_duration()))
1029 new_dur_val
= mv
->get_min_duration() ;
1034 drag_info
.last_pointer_frame
= pointer_frame
;
1035 drag_info
.cumulative_x_drag
= new_dur_val
;
1037 // we treat this as a special case, usually we want to send the identitiy of the caller
1038 // but in this case, that would trigger our socket handler to handle the event, sending
1039 // notification to the image compositor. This would be fine, except that we have not
1040 // finished the drag, we therefore do not want to sent notification until we have
1041 // completed the drag, only then do we want the image compositor notofied.
1042 // We therefore set the caller identity to the special case of 0
1043 mv
->set_duration(new_dur_val
, 0) ;
1046 show_verbose_time_cursor(new_dur_val
, 10) ;
1051 Editor::markerview_end_handle_end_trim (ArdourCanvas::Item
* item
, GdkEvent
* event
)
1053 MarkerView
* mv
= reinterpret_cast<MarkerView
*> (drag_info
.data
) ;
1055 if (drag_info
.cumulative_x_drag
== 0)
1061 nframes64_t new_duration
= (nframes64_t
)drag_info
.cumulative_x_drag
;
1062 mv
->set_duration(new_duration
, this) ;
1067 /* </CMT Additions file="editor_mouse.cc"> */
1075 /* <CMT Additions file="editor_route_list.cc"> */
1078 Editor::handle_new_imageframe_time_axis_view(const string
& track_name
, void* src
)
1080 ImageFrameTimeAxis
* iftav
;
1081 iftav
= new ImageFrameTimeAxis(track_name
, *this, *session
, *track_canvas
) ;
1082 iftav
->set_time_axis_name(track_name
, this) ;
1083 track_views
.push_back(iftav
) ;
1085 TreeModel::Row row
= *(route_display_model
->append());
1087 row
[route_display_columns
.text
] = iftav
->name();
1088 row
[route_display_columns
.tv
] = iftav
;
1089 route_list_display
.get_selection()->select (row
);
1091 iftav
->gui_changed
.connect(sigc::mem_fun(*this, &Editor::handle_gui_changes
)) ;
1095 Editor::handle_new_imageframe_marker_time_axis_view(const string
& track_name
, TimeAxisView
* marked_track
)
1097 MarkerTimeAxis
* mta
= new MarkerTimeAxis (*this, *this->session(), *track_canvas
, track_name
, marked_track
) ;
1098 ((ImageFrameTimeAxis
*)marked_track
)->add_marker_time_axis(mta
, this) ;
1099 track_views
.push_back(mta
) ;
1101 TreeModel::Row row
= *(route_display_model
->append());
1103 row
[route_display_columns
.text
] = mta
->name();
1104 row
[route_display_columns
.tv
] = mta
;
1105 route_list_display
.get_selection()->select (row
);
1109 /* </CMT Additions file="editor_route_list.cc"> */