Remove idiocy.
[ardour2.git] / gtk2_ardour / editor_imageframe.cc
blobd5d9481b5d2496ad2bfef3055e1847bab0a18e31
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"
45 using namespace Gtk;
46 using namespace PBD;
47 using namespace std;
49 TimeAxisView*
50 Editor::get_named_time_axis(const string & name)
52 TimeAxisView* tav = 0 ;
54 for (TrackViewList::const_iterator i = track_views.begin(); i != track_views.end(); ++i)
56 if (((TimeAxisView*)*i)->name() == name)
58 tav = ((TimeAxisView*)*i) ;
59 break ;
62 return(tav) ;
65 /* <CMT Additions file="editor.cc"> */
67 void
68 Editor::add_imageframe_time_axis(const string & track_name, void* src)
70 // check for duplicate name
71 if(get_named_time_axis(track_name))
73 warning << "Repeated time axis name" << std::endl ;
75 else
77 Gtkmm2ext::UI::instance()->call_slot(bind(mem_fun(*this, &Editor::handle_new_imageframe_time_axis_view),track_name, src)) ;
81 void
82 Editor::connect_to_image_compositor()
84 if(image_socket_listener == 0)
86 image_socket_listener = ImageFrameSocketHandler::create_instance(*this) ;
89 if(image_socket_listener->is_connected() == true)
91 return ;
94 // XXX should really put this somewhere safe
95 const char * host_ip = "127.0.0.1" ;
97 bool retcode = image_socket_listener->connect(host_ip, ardourvis::DEFAULT_PORT) ;
99 if(retcode == false)
101 // XXX need to get some return status here
102 warning << "Image Compositor Connection attempt failed" << std::endl ;
103 return ;
106 // add the socket to the gui loop, and keep the retuned tag value of the input
107 gint tag = gdk_input_add(image_socket_listener->get_socket_descriptor(), GDK_INPUT_READ,ImageFrameSocketHandler::image_socket_callback,image_socket_listener) ;
108 image_socket_listener->set_gdk_input_tag(tag) ;
111 void
112 Editor::scroll_timeaxis_to_imageframe_item(const TimeAxisViewItem* item)
114 // GTK2FIX
115 //nframes64_t offset = static_cast<nframes64_t>(frames_per_unit * (edit_hscroll_slider_width/2)) ;
116 nframes64_t offset = 0;
118 nframes64_t x_pos = 0 ;
120 if (item->get_position() < offset) {
121 x_pos = 0 ;
122 } else {
123 x_pos = item->get_position() - offset + (item->get_duration() / 2);
126 reset_x_origin (x_pos);
129 void
130 Editor::add_imageframe_marker_time_axis(const string & track_name, TimeAxisView* marked_track, void* src)
132 // Can we only bind 2 data Items?
133 // @todo we really want to bind the src attribute too, for the moment tracks can only be added remotely,
134 // so this is not too much of an issue, however will need to be looked at again
135 Gtkmm2ext::UI::instance()->call_slot(sigc::bind(mem_fun(*this, &Editor::handle_new_imageframe_marker_time_axis_view),track_name, marked_track)) ;
138 void
139 Editor::popup_imageframe_edit_menu(int button, int32_t time, ArdourCanvas::Item* ifv, bool with_item)
141 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(clicked_axisview) ;
143 if(ifta)
145 ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_selected_imageframe_group() ;
147 if(iftag)
149 ImageFrameView* selected_ifv = ifta->get_view()->get_selected_imageframe_view() ;
150 ifta->popup_imageframe_edit_menu(button, time, selected_ifv, with_item) ;
155 void
156 Editor::popup_marker_time_axis_edit_menu(int button, int32_t time, ArdourCanvas::Item* ifv, bool with_item)
158 MarkerTimeAxis* mta = dynamic_cast<MarkerTimeAxis*>(clicked_axisview) ;
160 if(mta)
162 MarkerView* selected_mv = mta->get_view()->get_selected_time_axis_item() ;
163 if(selected_mv)
165 mta->popup_marker_time_axis_edit_menu(button,time, selected_mv, with_item) ;
169 /* </CMT Additions file="editor.cc"> */
176 /* <CMT Additions file="editor_canvas_events.cc"> */
177 bool
178 Editor::canvas_imageframe_item_view_event (GdkEvent *event, ArdourCanvas::Item* item, ImageFrameView *ifv)
180 gint ret = FALSE ;
181 ImageFrameTimeAxisGroup* iftag = 0 ;
183 switch (event->type)
185 case GDK_BUTTON_PRESS:
186 case GDK_2BUTTON_PRESS:
187 case GDK_3BUTTON_PRESS:
188 clicked_axisview = &ifv->get_time_axis_view();
189 iftag = ifv->get_time_axis_group() ;
190 dynamic_cast<ImageFrameTimeAxis*>(clicked_axisview)->get_view()->set_selected_imageframe_view(iftag, ifv);
191 ret = button_press_handler (item, event, ImageFrameItem) ;
192 break ;
193 case GDK_BUTTON_RELEASE:
194 ret = button_release_handler (item, event, ImageFrameItem) ;
195 break ;
196 case GDK_MOTION_NOTIFY:
197 ret = motion_handler (item, event, ImageFrameItem) ;
198 break ;
199 default:
200 break ;
202 return(ret) ;
205 bool
206 Editor::canvas_imageframe_start_handle_event (GdkEvent *event, ArdourCanvas::Item* item, ImageFrameView *ifv)
208 gint ret = FALSE ;
209 ImageFrameTimeAxisGroup* iftag = 0 ;
211 switch (event->type)
213 case GDK_BUTTON_PRESS:
214 case GDK_2BUTTON_PRESS:
215 case GDK_3BUTTON_PRESS:
216 clicked_axisview = &ifv->get_time_axis_view() ;
217 iftag = ifv->get_time_axis_group() ;
218 dynamic_cast<ImageFrameTimeAxis*>(clicked_axisview)->get_view()->set_selected_imageframe_view(iftag, ifv);
220 ret = button_press_handler (item, event, ImageFrameHandleStartItem) ;
221 break ;
222 case GDK_BUTTON_RELEASE:
223 ret = button_release_handler (item, event, ImageFrameHandleStartItem) ;
224 break;
225 case GDK_MOTION_NOTIFY:
226 ret = motion_handler (item, event, ImageFrameHandleStartItem) ;
227 break ;
228 case GDK_ENTER_NOTIFY:
229 ret = enter_handler (item, event, ImageFrameHandleStartItem) ;
230 break ;
231 case GDK_LEAVE_NOTIFY:
232 ret = leave_handler (item, event, ImageFrameHandleStartItem) ;
233 break ;
234 default:
235 break ;
237 return(ret) ;
240 bool
241 Editor::canvas_imageframe_end_handle_event (GdkEvent *event, ArdourCanvas::Item* item, ImageFrameView *ifv)
243 gint ret = FALSE ;
244 ImageFrameTimeAxisGroup* iftag = 0 ;
246 switch (event->type)
248 case GDK_BUTTON_PRESS:
249 case GDK_2BUTTON_PRESS:
250 case GDK_3BUTTON_PRESS:
251 clicked_axisview = &ifv->get_time_axis_view() ;
252 iftag = ifv->get_time_axis_group() ;
253 dynamic_cast<ImageFrameTimeAxis*>(clicked_axisview)->get_view()->set_selected_imageframe_view(iftag, ifv);
255 ret = button_press_handler (item, event, ImageFrameHandleEndItem) ;
256 break ;
257 case GDK_BUTTON_RELEASE:
258 ret = button_release_handler (item, event, ImageFrameHandleEndItem) ;
259 break ;
260 case GDK_MOTION_NOTIFY:
261 ret = motion_handler (item, event, ImageFrameHandleEndItem) ;
262 break ;
263 case GDK_ENTER_NOTIFY:
264 ret = enter_handler (item, event, ImageFrameHandleEndItem) ;
265 break ;
266 case GDK_LEAVE_NOTIFY:
267 ret = leave_handler (item, event, ImageFrameHandleEndItem);
268 break ;
269 default:
270 break ;
272 return(ret) ;
275 bool
276 Editor::canvas_imageframe_view_event (GdkEvent* event, ArdourCanvas::Item* item, ImageFrameTimeAxis* ifta)
278 gint ret = FALSE ;
279 switch (event->type)
281 case GDK_BUTTON_PRESS:
282 case GDK_2BUTTON_PRESS:
283 case GDK_3BUTTON_PRESS:
284 clicked_axisview = ifta ;
285 ret = button_press_handler (item, event, ImageFrameTimeAxisItem) ;
286 break ;
287 case GDK_BUTTON_RELEASE:
288 ret = button_release_handler (item, event, ImageFrameTimeAxisItem) ;
289 break ;
290 case GDK_MOTION_NOTIFY:
291 break ;
292 default:
293 break ;
295 return(ret) ;
298 bool
299 Editor::canvas_marker_time_axis_view_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerTimeAxis* mta)
301 gint ret = FALSE ;
302 switch (event->type)
304 case GDK_BUTTON_PRESS:
305 case GDK_2BUTTON_PRESS:
306 case GDK_3BUTTON_PRESS:
307 clicked_axisview = mta ;
308 ret = button_press_handler(item, event, MarkerTimeAxisItem) ;
309 break ;
310 case GDK_BUTTON_RELEASE:
311 ret = button_release_handler(item, event, MarkerTimeAxisItem) ;
312 break ;
313 case GDK_MOTION_NOTIFY:
314 default:
315 break ;
317 return(ret) ;
321 bool
322 Editor::canvas_markerview_item_view_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerView* mta)
324 gint ret = FALSE ;
325 switch (event->type)
327 case GDK_BUTTON_PRESS:
328 case GDK_2BUTTON_PRESS:
329 case GDK_3BUTTON_PRESS:
330 clicked_axisview = &mta->get_time_axis_view() ;
331 dynamic_cast<MarkerTimeAxis*>(clicked_axisview)->get_view()->set_selected_time_axis_item(mta);
332 ret = button_press_handler(item, event, MarkerViewItem) ;
333 break ;
334 case GDK_BUTTON_RELEASE:
335 ret = button_release_handler(item, event, MarkerViewItem) ;
336 break ;
337 case GDK_MOTION_NOTIFY:
338 ret = motion_handler(item, event, MarkerViewItem) ;
339 break ;
340 default:
341 break ;
343 return(ret) ;
346 bool
347 Editor::canvas_markerview_start_handle_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerView* mta)
349 gint ret = FALSE ;
350 switch (event->type)
352 case GDK_BUTTON_PRESS:
353 case GDK_2BUTTON_PRESS:
354 case GDK_3BUTTON_PRESS:
355 clicked_axisview = &mta->get_time_axis_view() ;
356 dynamic_cast<MarkerTimeAxis*>(clicked_axisview)->get_view()->set_selected_time_axis_item(mta) ;
357 ret = button_press_handler(item, event, MarkerViewHandleStartItem) ;
358 break ;
359 case GDK_BUTTON_RELEASE:
360 ret = button_release_handler(item, event, MarkerViewHandleStartItem) ;
361 break ;
362 case GDK_MOTION_NOTIFY:
363 ret = motion_handler(item, event, MarkerViewHandleStartItem) ;
364 break ;
365 case GDK_ENTER_NOTIFY:
366 ret = enter_handler(item, event, MarkerViewHandleStartItem) ;
367 break ;
368 case GDK_LEAVE_NOTIFY:
369 ret = leave_handler(item, event, MarkerViewHandleStartItem) ;
370 break ;
371 default:
372 break ;
374 return(ret) ;
377 bool
378 Editor::canvas_markerview_end_handle_event (GdkEvent* event, ArdourCanvas::Item* item, MarkerView* mta)
380 gint ret = FALSE ;
381 switch (event->type)
383 case GDK_BUTTON_PRESS:
384 case GDK_2BUTTON_PRESS:
385 case GDK_3BUTTON_PRESS:
386 clicked_axisview = &mta->get_time_axis_view() ;
387 dynamic_cast<MarkerTimeAxis*>(clicked_axisview)->get_view()->set_selected_time_axis_item(mta) ;
388 ret = button_press_handler(item, event, MarkerViewHandleEndItem) ;
389 break ;
390 case GDK_BUTTON_RELEASE:
391 ret = button_release_handler(item, event, MarkerViewHandleEndItem) ;
392 break ;
393 case GDK_MOTION_NOTIFY:
394 ret = motion_handler(item, event, MarkerViewHandleEndItem) ;
395 break ;
396 case GDK_ENTER_NOTIFY:
397 ret = enter_handler(item, event, MarkerViewHandleEndItem) ;
398 break ;
399 case GDK_LEAVE_NOTIFY:
400 ret = leave_handler(item, event, MarkerViewHandleEndItem) ;
401 break ;
402 default:
403 break ;
405 return(ret) ;
409 /* </CMT Additions file="editor_canvas_events.cc"> */
413 ---------------------------------------------------------------------------------------------------
414 ---------------------------------------------------------------------------------------------------
415 ---------------------------------------------------------------------------------------------------
420 /* <CMT Additions file="editor_mouse.cc"> */
422 void
423 Editor::start_imageframe_grab(ArdourCanvas::Item* item, GdkEvent* event)
425 ImageFrameView* ifv = ((ImageFrameTimeAxis*)clicked_axisview)->get_view()->get_selected_imageframe_view() ;
426 drag_info.copy = false ;
427 drag_info.item = item ;
428 drag_info.data = ifv ;
429 drag_info.motion_callback = &Editor::imageframe_drag_motion_callback;
430 drag_info.finished_callback = &Editor::timeaxis_item_drag_finished_callback;
431 drag_info.last_frame_position = ifv->get_position() ;
433 drag_info.source_trackview = &ifv->get_time_axis_view() ;
434 drag_info.dest_trackview = drag_info.source_trackview;
436 /* this is subtle. raising the regionview itself won't help,
437 because raise_to_top() just puts the item on the top of
438 its parent's stack. so, we need to put the trackview canvas_display group
439 on the top, since its parent is the whole canvas.
441 however, this hides the measure bars within that particular trackview,
442 so move them to the top afterwards.
445 drag_info.item->raise_to_top();
446 drag_info.source_trackview->canvas_display->raise_to_top();
447 //time_line_group->raise_to_top();
448 cursor_group->raise_to_top ();
450 start_grab(event) ;
452 drag_info.pointer_frame_offset = pixel_to_frame(drag_info.grab_x) - drag_info.last_frame_position;
456 void
457 Editor::start_markerview_grab(ArdourCanvas::Item* item, GdkEvent* event)
459 MarkerView* mv = ((MarkerTimeAxis*)clicked_axisview)->get_view()->get_selected_time_axis_item() ;
460 drag_info.copy = false ;
461 drag_info.item = item ;
462 drag_info.data = mv ;
463 drag_info.motion_callback = &Editor::markerview_drag_motion_callback;
464 drag_info.finished_callback = &Editor::timeaxis_item_drag_finished_callback;
465 drag_info.last_frame_position = mv->get_position() ;
467 drag_info.source_trackview = &mv->get_time_axis_view() ;
468 drag_info.dest_trackview = drag_info.source_trackview;
470 /* this is subtle. raising the regionview itself won't help,
471 because raise_to_top() just puts the item on the top of
472 its parent's stack. so, we need to put the trackview canvas_display group
473 on the top, since its parent is the whole canvas.
475 however, this hides the measure bars within that particular trackview,
476 so move them to the top afterwards.
479 drag_info.item->raise_to_top();
480 drag_info.source_trackview->canvas_display->raise_to_top();
481 //time_line_group->raise_to_top();
482 cursor_group->raise_to_top ();
484 start_grab(event) ;
486 drag_info.pointer_frame_offset = pixel_to_frame(drag_info.grab_x) - drag_info.last_frame_position ;
490 void
491 Editor::markerview_drag_motion_callback(ArdourCanvas::Item*, GdkEvent* event)
493 double cx, cy ;
495 MarkerView* mv = reinterpret_cast<MarkerView*>(drag_info.data) ;
496 nframes64_t pending_region_position ;
497 nframes64_t pointer_frame ;
499 pointer_frame = event_frame(event, &cx, &cy) ;
501 snap_to(pointer_frame) ;
503 if (pointer_frame > (nframes64_t) drag_info.pointer_frame_offset)
505 pending_region_position = pointer_frame - drag_info.pointer_frame_offset ;
506 snap_to(pending_region_position) ;
508 // we dont allow marker items to extend beyond, or in front of the marked items so
509 // cap the value to the marked items position and duration
510 if((pending_region_position + mv->get_duration()) >= ((mv->get_marked_item()->get_position()) + (mv->get_marked_item()->get_duration())))
512 pending_region_position = (mv->get_marked_item()->get_position() + mv->get_marked_item()->get_duration()) - (mv->get_duration()) ;
514 else if(pending_region_position <= mv->get_marked_item()->get_position())
516 pending_region_position = mv->get_marked_item()->get_position() ;
519 else
521 pending_region_position = mv->get_marked_item()->get_position() ;
524 drag_info.last_frame_position = pending_region_position ;
526 // we treat this as a special case, usually we want to send the identitiy of the caller
527 // but in this case, that would trigger our socket handler to handle the event, sending
528 // notification to the image compositor. This would be fine, except that we have not
529 // finished the drag, we therefore do not want to sent notification until we have
530 // completed the drag, only then do we want the image compositor notofied.
531 // We therefore set the caller identity to the special case of 0
532 mv->set_position(pending_region_position, 0) ;
534 show_verbose_time_cursor(pending_region_position) ;
537 void
538 Editor::imageframe_drag_motion_callback(ArdourCanvas::Item*, GdkEvent* event)
540 double cx, cy ;
542 ImageFrameView* ifv = reinterpret_cast<ImageFrameView*>(drag_info.data) ;
544 nframes64_t pending_region_position;
545 nframes64_t pointer_frame;
547 pointer_frame = event_frame(event, &cx, &cy) ;
549 snap_to(pointer_frame) ;
551 if (pointer_frame > (nframes64_t) drag_info.pointer_frame_offset)
553 pending_region_position = pointer_frame - drag_info.pointer_frame_offset ;
554 snap_to(pending_region_position) ;
556 else
558 pending_region_position = 0 ;
561 drag_info.grab_x = cx;
562 //drag_info.last_frame_position = pending_region_position ;
563 drag_info.current_pointer_frame = pending_region_position ;
565 // we treat this as a special case, usually we want to send the identitiy of the caller
566 // but in this case, that would trigger our socket handler to handle the event, sending
567 // notification to the image compositor. This would be fine, except that we have not
568 // finished the drag, we therefore do not want to sent notification until we have
569 // completed the drag, only then do we want the image compositor notofied.
570 // We therefore set the caller identity to the special case of 0
571 ifv->set_position(pending_region_position, 0) ;
573 show_verbose_time_cursor(pending_region_position) ;
576 void
577 Editor::timeaxis_item_drag_finished_callback(ArdourCanvas::Item*, GdkEvent* event)
579 nframes64_t where ;
580 TimeAxisViewItem* tavi = reinterpret_cast<TimeAxisViewItem*>(drag_info.data) ;
582 bool item_x_movement = (drag_info.last_frame_position != tavi->get_position()) ;
584 hide_verbose_canvas_cursor() ;
586 /* no x or y movement either means the regionview hasn't been moved, or has been moved
587 but is back in it's original position/trackview.*/
589 if(!item_x_movement && event && event->type == GDK_BUTTON_RELEASE)
591 /* No motion: either set the current region, or align the clicked region
592 with the current one.
594 return;
597 if(item_x_movement)
599 /* base the new region position on the current position of the regionview.*/
600 where = drag_info.current_pointer_frame ;
602 // final call to set position after the motion to tell interested parties of the new position
603 tavi->set_position(where, this) ;
605 else
607 //where = tavi->get_position() ;
614 void
615 Editor::imageframe_start_handle_op(ArdourCanvas::Item* item, GdkEvent* event)
617 // get the selected item from the parent time axis
618 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(clicked_axisview) ;
619 if(ifta)
621 ImageFrameView* ifv = ifta->get_view()->get_selected_imageframe_view() ;
623 if (ifv == 0) {
624 fatal << _("programming error: no ImageFrameView selected") << endmsg;
625 /*NOTREACHED*/
626 return ;
629 drag_info.item = ifv->get_canvas_frame() ;
630 drag_info.data = ifv;
631 drag_info.grab_x = event->motion.x;
632 drag_info.cumulative_x_drag = 0;
633 drag_info.motion_callback = &Editor::imageframe_start_handle_trim_motion ;
634 drag_info.finished_callback = &Editor::imageframe_start_handle_end_trim ;
636 start_grab(event) ;
638 show_verbose_time_cursor(ifv->get_position(), 10) ;
642 void
643 Editor::imageframe_end_handle_op(ArdourCanvas::Item* item, GdkEvent* event)
645 // get the selected item from the parent time axis
646 ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(clicked_axisview) ;
648 if(ifta)
650 ImageFrameView* ifv = ifta->get_view()->get_selected_imageframe_view() ;
652 if (ifv == 0)
654 fatal << _("programming error: no ImageFrameView selected") << endmsg ;
655 /*NOTREACHED*/
656 return ;
659 drag_info.item = ifv->get_canvas_frame() ;
660 drag_info.data = ifv ;
661 drag_info.grab_x = event->motion.x ;
662 drag_info.cumulative_x_drag = 0 ;
663 drag_info.motion_callback = &Editor::imageframe_end_handle_trim_motion ;
664 drag_info.finished_callback = &Editor::imageframe_end_handle_end_trim ;
666 start_grab(event, trimmer_cursor) ;
668 show_verbose_time_cursor(ifv->get_position() + ifv->get_duration(), 10) ;
672 void
673 Editor::imageframe_start_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* event)
675 ImageFrameView* ifv = reinterpret_cast<ImageFrameView*> (drag_info.data) ;
677 nframes64_t start = 0 ;
678 nframes64_t end = 0 ;
679 nframes64_t pointer_frame = event_frame(event) ;
681 // chekc th eposition of the item is not locked
682 if(!ifv->get_position_locked()) {
683 snap_to(pointer_frame) ;
685 if(pointer_frame != drag_info.last_pointer_frame) {
686 start = ifv->get_position() ;
687 end = ifv->get_position() + ifv->get_duration() ;
689 if (pointer_frame > end) {
690 start = end ;
691 } else {
692 start = pointer_frame ;
695 // are we getting bigger or smaller?
696 nframes64_t new_dur_val = end - start ;
698 // start handle, so a smaller pointer frame increases our component size
699 if(pointer_frame <= drag_info.grab_frame)
701 if(ifv->get_max_duration_active() && (new_dur_val > ifv->get_max_duration()))
703 new_dur_val = ifv->get_max_duration() ;
704 start = end - new_dur_val ;
706 else
708 // current values are ok
711 else
713 if(ifv->get_min_duration_active() && (new_dur_val < ifv->get_min_duration()))
715 new_dur_val = ifv->get_min_duration() ;
716 start = end - new_dur_val ;
718 else
720 // current values are ok
724 drag_info.last_pointer_frame = pointer_frame ;
726 /* re-calculatethe duration and position of the imageframeview */
727 drag_info.cumulative_x_drag = new_dur_val ;
729 // we treat this as a special case, usually we want to send the identitiy of the caller
730 // but in this case, that would trigger our socket handler to handle the event, sending
731 // notification to the image compositor. This would be fine, except that we have not
732 // finished the drag, we therefore do not want to sent notification until we have
733 // completed the drag, only then do we want the image compositor notofied.
734 // We therefore set the caller identity to the special case of 0
735 ifv->set_duration(new_dur_val, 0) ;
736 ifv->set_position(start, 0) ;
740 show_verbose_time_cursor(start, 10) ;
743 void
744 Editor::imageframe_start_handle_end_trim(ArdourCanvas::Item* item, GdkEvent* event)
746 ImageFrameView* ifv = reinterpret_cast<ImageFrameView *> (drag_info.data) ;
748 if (drag_info.cumulative_x_drag == 0)
750 /* just a click */
752 else
754 nframes64_t temp = ifv->get_position() + ifv->get_duration() ;
756 ifv->set_position((nframes64_t) (temp - drag_info.cumulative_x_drag), this) ;
757 ifv->set_duration((nframes64_t) drag_info.cumulative_x_drag, this) ;
761 void
762 Editor::imageframe_end_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* event)
764 ImageFrameView* ifv = reinterpret_cast<ImageFrameView *> (drag_info.data) ;
766 nframes64_t start = 0 ;
767 nframes64_t end = 0 ;
768 nframes64_t pointer_frame = event_frame(event) ;
769 nframes64_t new_dur_val = 0 ;
771 snap_to(pointer_frame) ;
773 if (pointer_frame != drag_info.last_pointer_frame)
775 start = ifv->get_position() ;
776 end = ifv->get_position() + ifv->get_duration() ;
777 if (pointer_frame < start)
779 end = start ;
781 else
783 end = pointer_frame ;
786 new_dur_val = end - start ;
788 // are we getting bigger or smaller?
789 if(pointer_frame >= drag_info.last_pointer_frame)
791 if(ifv->get_max_duration_active() && (new_dur_val > ifv->get_max_duration()))
793 new_dur_val = ifv->get_max_duration() ;
796 else
798 if(ifv->get_min_duration_active() && (new_dur_val < ifv->get_min_duration()))
800 new_dur_val = ifv->get_min_duration() ;
804 drag_info.last_pointer_frame = pointer_frame ;
805 drag_info.cumulative_x_drag = new_dur_val ;
807 // we treat this as a special case, usually we want to send the identitiy of the caller
808 // but in this case, that would trigger our socket handler to handle the event, sending
809 // notification to the image compositor. This would be fine, except that we have not
810 // finished the drag, we therefore do not want to sent notification until we have
811 // completed the drag, only then do we want the image compositor notofied.
812 // We therefore set the caller identity to the special case of 0
813 ifv->set_duration(new_dur_val, 0) ;
816 show_verbose_time_cursor(new_dur_val, 10) ;
820 void
821 Editor::imageframe_end_handle_end_trim (ArdourCanvas::Item* item, GdkEvent* event)
823 ImageFrameView* ifv = reinterpret_cast<ImageFrameView *> (drag_info.data) ;
825 if (drag_info.cumulative_x_drag == 0)
827 /* just a click */
829 else
831 nframes64_t new_duration = (nframes64_t)drag_info.cumulative_x_drag ;
832 if((new_duration <= ifv->get_max_duration()) && (new_duration >= ifv->get_min_duration()))
834 ifv->set_duration(new_duration, this) ;
840 void
841 Editor::markerview_item_start_handle_op(ArdourCanvas::Item* item, GdkEvent* event)
843 MarkerView* mv = reinterpret_cast<MarkerTimeAxis*>(clicked_axisview)->get_view()->get_selected_time_axis_item() ;
845 if (mv == 0)
847 fatal << _("programming error: no MarkerView selected") << endmsg ;
848 /*NOTREACHED*/
849 return ;
852 drag_info.item = mv->get_canvas_frame() ;
853 drag_info.data = mv;
854 drag_info.grab_x = event->motion.x;
856 drag_info.cumulative_x_drag = 0 ;
857 drag_info.motion_callback = &Editor::markerview_start_handle_trim_motion ;
858 drag_info.finished_callback = &Editor::markerview_start_handle_end_trim ;
860 start_grab(event, trimmer_cursor) ;
863 void
864 Editor::markerview_item_end_handle_op(ArdourCanvas::Item* item, GdkEvent* event)
866 MarkerView* mv = reinterpret_cast<MarkerTimeAxis*>(clicked_axisview)->get_view()->get_selected_time_axis_item() ;
867 if (mv == 0)
869 fatal << _("programming error: no MarkerView selected") << endmsg ;
870 /*NOTREACHED*/
871 return ;
874 drag_info.item = mv->get_canvas_frame() ;
875 drag_info.data = mv ;
876 drag_info.grab_x = event->motion.x ;
877 drag_info.cumulative_x_drag = 0 ;
879 drag_info.motion_callback = &Editor::markerview_end_handle_trim_motion ;
880 drag_info.finished_callback = &Editor::markerview_end_handle_end_trim ;
882 start_grab(event, trimmer_cursor) ;
886 void
887 Editor::markerview_start_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* event)
889 MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
891 nframes64_t start = 0 ;
892 nframes64_t end = 0 ;
893 nframes64_t pointer_frame = event_frame(event) ;
895 // chekc th eposition of the item is not locked
896 if(!mv->get_position_locked())
898 snap_to(pointer_frame) ;
899 if(pointer_frame != drag_info.last_pointer_frame)
901 start = mv->get_position() ;
902 end = mv->get_position() + mv->get_duration() ;
904 if (pointer_frame > end)
906 start = end ;
908 else
910 start = pointer_frame ;
913 // are we getting bigger or smaller?
914 nframes64_t new_dur_val = end - start ;
916 if(pointer_frame <= drag_info.grab_frame)
918 if(mv->get_max_duration_active() && (new_dur_val > mv->get_max_duration()))
920 new_dur_val = mv->get_max_duration() ;
921 start = end - new_dur_val ;
923 else
925 // current values are ok
928 else
930 if(mv->get_min_duration_active() && (new_dur_val < mv->get_min_duration()))
932 new_dur_val = mv->get_min_duration() ;
933 start = end - new_dur_val ;
935 else
937 // current values are ok
941 drag_info.last_pointer_frame = pointer_frame ;
943 /* re-calculatethe duration and position of the imageframeview */
944 drag_info.cumulative_x_drag = new_dur_val ;
946 // we treat this as a special case, usually we want to send the identitiy of the caller
947 // but in this case, that would trigger our socket handler to handle the event, sending
948 // notification to the image compositor. This would be fine, except that we have not
949 // finished the drag, we therefore do not want to sent notification until we have
950 // completed the drag, only then do we want the image compositor notofied.
951 // We therefore set the caller identity to the special case of 0
952 mv->set_duration(new_dur_val, 0) ;
953 mv->set_position(start, 0) ;
957 show_verbose_time_cursor(start, 10) ;
960 void
961 Editor::markerview_start_handle_end_trim(ArdourCanvas::Item* item, GdkEvent* event)
963 MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
965 if (drag_info.cumulative_x_drag == 0)
967 /* just a click */
969 else
971 nframes64_t temp = mv->get_position() + mv->get_duration() ;
973 mv->set_position((nframes64_t) (temp - drag_info.cumulative_x_drag), this) ;
974 mv->set_duration((nframes64_t) drag_info.cumulative_x_drag, this) ;
978 void
979 Editor::markerview_end_handle_trim_motion(ArdourCanvas::Item* item, GdkEvent* event)
981 MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
983 nframes64_t start = 0 ;
984 nframes64_t end = 0 ;
985 nframes64_t pointer_frame = event_frame(event) ;
986 nframes64_t new_dur_val = 0 ;
988 snap_to(pointer_frame) ;
990 if (pointer_frame != drag_info.last_pointer_frame)
992 start = mv->get_position() ;
993 end = mv->get_position() + mv->get_duration() ;
995 if(pointer_frame < start)
997 end = start ;
999 else
1001 end = pointer_frame ;
1004 new_dur_val = end - start ;
1006 // are we getting bigger or smaller?
1007 if(pointer_frame >= drag_info.last_pointer_frame)
1009 // we cant extend beyond the item we are marking
1010 ImageFrameView* marked_item = mv->get_marked_item() ;
1011 nframes64_t marked_end = marked_item->get_position() + marked_item->get_duration() ;
1013 if(mv->get_max_duration_active() && (new_dur_val > mv->get_max_duration()))
1015 if((start + mv->get_max_duration()) > marked_end)
1017 new_dur_val = marked_end - start ;
1019 else
1021 new_dur_val = mv->get_max_duration() ;
1024 else if(end > marked_end)
1026 new_dur_val = marked_end - start ;
1029 else
1031 if(mv->get_min_duration_active() && (new_dur_val < mv->get_min_duration()))
1033 new_dur_val = mv->get_min_duration() ;
1038 drag_info.last_pointer_frame = pointer_frame ;
1039 drag_info.cumulative_x_drag = new_dur_val ;
1041 // we treat this as a special case, usually we want to send the identitiy of the caller
1042 // but in this case, that would trigger our socket handler to handle the event, sending
1043 // notification to the image compositor. This would be fine, except that we have not
1044 // finished the drag, we therefore do not want to sent notification until we have
1045 // completed the drag, only then do we want the image compositor notofied.
1046 // We therefore set the caller identity to the special case of 0
1047 mv->set_duration(new_dur_val, 0) ;
1050 show_verbose_time_cursor(new_dur_val, 10) ;
1054 void
1055 Editor::markerview_end_handle_end_trim (ArdourCanvas::Item* item, GdkEvent* event)
1057 MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
1059 if (drag_info.cumulative_x_drag == 0)
1061 /* just a click */
1063 else
1065 nframes64_t new_duration = (nframes64_t)drag_info.cumulative_x_drag ;
1066 mv->set_duration(new_duration, this) ;
1071 /* </CMT Additions file="editor_mouse.cc"> */
1079 /* <CMT Additions file="editor_route_list.cc"> */
1081 void
1082 Editor::handle_new_imageframe_time_axis_view(const string & track_name, void* src)
1084 ImageFrameTimeAxis* iftav ;
1085 iftav = new ImageFrameTimeAxis(track_name, *this, *session, *track_canvas) ;
1086 iftav->set_time_axis_name(track_name, this) ;
1087 track_views.push_back(iftav) ;
1089 TreeModel::Row row = *(route_display_model->append());
1091 row[route_display_columns.text] = iftav->name();
1092 row[route_display_columns.tv] = iftav;
1093 route_list_display.get_selection()->select (row);
1095 iftav->GoingAway.connect(bind(mem_fun(*this, &Editor::remove_route), (TimeAxisView*)iftav)) ;
1096 iftav->gui_changed.connect(mem_fun(*this, &Editor::handle_gui_changes)) ;
1099 void
1100 Editor::handle_new_imageframe_marker_time_axis_view(const string & track_name, TimeAxisView* marked_track)
1102 MarkerTimeAxis* mta = new MarkerTimeAxis (*this, *this->current_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);
1112 mta->GoingAway.connect(bind(mem_fun(*this, &Editor::remove_route), (TimeAxisView*)mta)) ;
1116 /* </CMT Additions file="editor_route_list.cc"> */