Remove erroneous assert which I added earlier.
[ardour2.git] / gtk2_ardour / editor_imageframe.cc
blob752e43a5859fa49e6716be8d70241e17d24bb63e
1 /*
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"
28 #include "editor.h"
29 #include "i18n.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>
38 #include <unistd.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"
46 using namespace Gtk;
47 using namespace PBD;
48 using namespace std;
50 TimeAxisView*
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) ;
60 break ;
63 return(tav) ;
66 /* <CMT Additions file="editor.cc"> */
68 void
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 ;
76 else
78 Gtkmm2ext::UI::instance()->call_slot (boost::bind (&Editor::handle_new_imageframe_time_axis_view, this,track_name, src));
82 void
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)
92 return ;
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) ;
100 if(retcode == false)
102 // XXX need to get some return status here
103 warning << "Image Compositor Connection attempt failed" << std::endl ;
104 return ;
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) ;
112 void
113 Editor::scroll_timeaxis_to_imageframe_item(const TimeAxisViewItem* item)
115 // GTK2FIX
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) {
122 x_pos = 0 ;
123 } else {
124 x_pos = item->get_position() - offset + (item->get_duration() / 2);
127 reset_x_origin (x_pos);
130 void
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));
139 void
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) ;
144 if(ifta)
146 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_selected_imageframe_group() ;
148 if(iftag)
150 ImageFrameView* selected_ifv = ifta->get_view()->get_selected_imageframe_view() ;
151 ifta->popup_imageframe_edit_menu(button, time, selected_ifv, with_item) ;
156 void
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) ;
161 if(mta)
163 MarkerView* selected_mv = mta->get_view()->get_selected_time_axis_item() ;
164 if(selected_mv)
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"> */
173 bool
174 Editor::canvas_imageframe_item_view_event (GdkEvent *event, ArdourCanvas::Item* item, ImageFrameView *ifv)
176 gint ret = FALSE ;
177 ImageFrameTimeAxisGroup* iftag = 0 ;
179 switch (event->type)
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) ;
188 break ;
189 case GDK_BUTTON_RELEASE:
190 ret = button_release_handler (item, event, ImageFrameItem) ;
191 break ;
192 case GDK_MOTION_NOTIFY:
193 ret = motion_handler (item, event, ImageFrameItem) ;
194 break ;
195 default:
196 break ;
198 return(ret) ;
201 bool
202 Editor::canvas_imageframe_start_handle_event (GdkEvent *event, ArdourCanvas::Item* item, ImageFrameView *ifv)
204 gint ret = FALSE ;
205 ImageFrameTimeAxisGroup* iftag = 0 ;
207 switch (event->type)
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) ;
217 break ;
218 case GDK_BUTTON_RELEASE:
219 ret = button_release_handler (item, event, ImageFrameHandleStartItem) ;
220 break;
221 case GDK_MOTION_NOTIFY:
222 ret = motion_handler (item, event, ImageFrameHandleStartItem) ;
223 break ;
224 case GDK_ENTER_NOTIFY:
225 ret = enter_handler (item, event, ImageFrameHandleStartItem) ;
226 break ;
227 case GDK_LEAVE_NOTIFY:
228 ret = leave_handler (item, event, ImageFrameHandleStartItem) ;
229 break ;
230 default:
231 break ;
233 return(ret) ;
236 bool
237 Editor::canvas_imageframe_end_handle_event (GdkEvent *event, ArdourCanvas::Item* item, ImageFrameView *ifv)
239 gint ret = FALSE ;
240 ImageFrameTimeAxisGroup* iftag = 0 ;
242 switch (event->type)
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) ;
252 break ;
253 case GDK_BUTTON_RELEASE:
254 ret = button_release_handler (item, event, ImageFrameHandleEndItem) ;
255 break ;
256 case GDK_MOTION_NOTIFY:
257 ret = motion_handler (item, event, ImageFrameHandleEndItem) ;
258 break ;
259 case GDK_ENTER_NOTIFY:
260 ret = enter_handler (item, event, ImageFrameHandleEndItem) ;
261 break ;
262 case GDK_LEAVE_NOTIFY:
263 ret = leave_handler (item, event, ImageFrameHandleEndItem);
264 break ;
265 default:
266 break ;
268 return(ret) ;
271 bool
272 Editor::canvas_imageframe_view_event (GdkEvent* event, ArdourCanvas::Item* item, ImageFrameTimeAxis* ifta)
274 gint ret = FALSE ;
275 switch (event->type)
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) ;
282 break ;
283 case GDK_BUTTON_RELEASE:
284 ret = button_release_handler (item, event, ImageFrameTimeAxisItem) ;
285 break ;
286 case GDK_MOTION_NOTIFY:
287 break ;
288 default:
289 break ;
291 return(ret) ;
294 bool
295 Editor::canvas_marker_time_axis_view_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerTimeAxis* mta)
297 gint ret = FALSE ;
298 switch (event->type)
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) ;
305 break ;
306 case GDK_BUTTON_RELEASE:
307 ret = button_release_handler(item, event, MarkerTimeAxisItem) ;
308 break ;
309 case GDK_MOTION_NOTIFY:
310 default:
311 break ;
313 return(ret) ;
317 bool
318 Editor::canvas_markerview_item_view_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerView* mta)
320 gint ret = FALSE ;
321 switch (event->type)
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) ;
329 break ;
330 case GDK_BUTTON_RELEASE:
331 ret = button_release_handler(item, event, MarkerViewItem) ;
332 break ;
333 case GDK_MOTION_NOTIFY:
334 ret = motion_handler(item, event, MarkerViewItem) ;
335 break ;
336 default:
337 break ;
339 return(ret) ;
342 bool
343 Editor::canvas_markerview_start_handle_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerView* mta)
345 gint ret = FALSE ;
346 switch (event->type)
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) ;
354 break ;
355 case GDK_BUTTON_RELEASE:
356 ret = button_release_handler(item, event, MarkerViewHandleStartItem) ;
357 break ;
358 case GDK_MOTION_NOTIFY:
359 ret = motion_handler(item, event, MarkerViewHandleStartItem) ;
360 break ;
361 case GDK_ENTER_NOTIFY:
362 ret = enter_handler(item, event, MarkerViewHandleStartItem) ;
363 break ;
364 case GDK_LEAVE_NOTIFY:
365 ret = leave_handler(item, event, MarkerViewHandleStartItem) ;
366 break ;
367 default:
368 break ;
370 return(ret) ;
373 bool
374 Editor::canvas_markerview_end_handle_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerView* mta)
376 gint ret = FALSE ;
377 switch (event->type)
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) ;
385 break ;
386 case GDK_BUTTON_RELEASE:
387 ret = button_release_handler(item, event, MarkerViewHandleEndItem) ;
388 break ;
389 case GDK_MOTION_NOTIFY:
390 ret = motion_handler(item, event, MarkerViewHandleEndItem) ;
391 break ;
392 case GDK_ENTER_NOTIFY:
393 ret = enter_handler(item, event, MarkerViewHandleEndItem) ;
394 break ;
395 case GDK_LEAVE_NOTIFY:
396 ret = leave_handler(item, event, MarkerViewHandleEndItem) ;
397 break ;
398 default:
399 break ;
401 return(ret) ;
405 /* </CMT Additions file="editor_canvas_events.cc"> */
409 ---------------------------------------------------------------------------------------------------
410 ---------------------------------------------------------------------------------------------------
411 ---------------------------------------------------------------------------------------------------
416 /* <CMT Additions file="editor_mouse.cc"> */
418 void
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 ();
446 start_grab(event) ;
448 drag_info.pointer_frame_offset = pixel_to_frame(drag_info.grab_x) - drag_info.last_frame_position;
452 void
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 ();
480 start_grab(event) ;
482 drag_info.pointer_frame_offset = pixel_to_frame(drag_info.grab_x) - drag_info.last_frame_position ;
486 void
487 Editor::markerview_drag_motion_callback(ArdourCanvas::Item*, GdkEvent* event)
489 double cx, cy ;
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() ;
515 else
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) ;
533 void
534 Editor::imageframe_drag_motion_callback(ArdourCanvas::Item*, GdkEvent* event)
536 double cx, cy ;
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) ;
552 else
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) ;
572 void
573 Editor::timeaxis_item_drag_finished_callback(ArdourCanvas::Item*, GdkEvent* event)
575 framepos_t where ;
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.
590 return;
593 if(item_x_movement)
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) ;
601 else
603 //where = tavi->get_position() ;
610 void
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) ;
615 if(ifta)
617 ImageFrameView* ifv = ifta->get_view()->get_selected_imageframe_view() ;
619 if (ifv == 0) {
620 fatal << _("programming error: no ImageFrameView selected") << endmsg;
621 /*NOTREACHED*/
622 return ;
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 ;
632 start_grab(event) ;
634 show_verbose_time_cursor(ifv->get_position(), 10) ;
638 void
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) ;
644 if(ifta)
646 ImageFrameView* ifv = ifta->get_view()->get_selected_imageframe_view() ;
648 if (ifv == 0)
650 fatal << _("programming error: no ImageFrameView selected") << endmsg ;
651 /*NOTREACHED*/
652 return ;
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) ;
668 void
669 Editor::imageframe_start_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* event)
671 ImageFrameView* ifv = reinterpret_cast<ImageFrameView*> (drag_info.data) ;
673 framepos_t start = 0 ;
674 framepos_t end = 0 ;
675 framepos_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) {
686 start = end ;
687 } else {
688 start = pointer_frame ;
691 // are we getting bigger or smaller?
692 framepos_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 ;
702 else
704 // current values are ok
707 else
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 ;
714 else
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) ;
739 void
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)
746 /* just a click */
748 else
750 framepos_t temp = ifv->get_position() + ifv->get_duration() ;
752 ifv->set_position((framepos_t) (temp - drag_info.cumulative_x_drag), this) ;
753 ifv->set_duration((framepos_t) drag_info.cumulative_x_drag, this) ;
757 void
758 Editor::imageframe_end_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* event)
760 ImageFrameView* ifv = reinterpret_cast<ImageFrameView *> (drag_info.data) ;
762 framepos_t start = 0 ;
763 framepos_t end = 0 ;
764 framepos_t pointer_frame = event_frame(event) ;
765 framepos_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)
775 end = start ;
777 else
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() ;
792 else
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) ;
816 void
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)
823 /* just a click */
825 else
827 framepos_t new_duration = (framepos_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) ;
836 void
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() ;
841 if (mv == 0)
843 fatal << _("programming error: no MarkerView selected") << endmsg ;
844 /*NOTREACHED*/
845 return ;
848 drag_info.item = mv->get_canvas_frame() ;
849 drag_info.data = mv;
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) ;
859 void
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() ;
863 if (mv == 0)
865 fatal << _("programming error: no MarkerView selected") << endmsg ;
866 /*NOTREACHED*/
867 return ;
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) ;
882 void
883 Editor::markerview_start_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* event)
885 MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
887 framepos_t start = 0 ;
888 framepos_t end = 0 ;
889 framepos_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)
902 start = end ;
904 else
906 start = pointer_frame ;
909 // are we getting bigger or smaller?
910 framepos_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 ;
919 else
921 // current values are ok
924 else
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 ;
931 else
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) ;
956 void
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)
963 /* just a click */
965 else
967 framepos_t temp = mv->get_position() + mv->get_duration() ;
969 mv->set_position((framepos_t) (temp - drag_info.cumulative_x_drag), this) ;
970 mv->set_duration((framepos_t) drag_info.cumulative_x_drag, this) ;
974 void
975 Editor::markerview_end_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* event)
977 MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
979 framepos_t start = 0 ;
980 framepos_t end = 0 ;
981 framepos_t pointer_frame = event_frame(event) ;
982 framepos_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)
993 end = start ;
995 else
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 framepos_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 ;
1015 else
1017 new_dur_val = mv->get_max_duration() ;
1020 else if(end > marked_end)
1022 new_dur_val = marked_end - start ;
1025 else
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) ;
1050 void
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)
1057 /* just a click */
1059 else
1061 framepos_t new_duration = (framepos_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"> */
1077 void
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)) ;
1094 void
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"> */