summaryrefslogtreecommitdiff
path: root/gtk2_ardour/editor_imageframe.cc
diff options
context:
space:
mode:
authorTaybin Rutkin <taybin@taybin.com>2005-09-25 18:42:24 +0000
committerTaybin Rutkin <taybin@taybin.com>2005-09-25 18:42:24 +0000
commit209d967b1bb80a9735d690d8f4f0455ecb9970ca (patch)
tree9d76ddcd7c1ac9d91bb2b1a33d31b66ce4ded5de /gtk2_ardour/editor_imageframe.cc
parente4b9aed743fc765219ac775905a221c017c88fba (diff)
Initial import of gtk2_ardour.
git-svn-id: svn://localhost/trunk/ardour2@24 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'gtk2_ardour/editor_imageframe.cc')
-rw-r--r--gtk2_ardour/editor_imageframe.cc1179
1 files changed, 1179 insertions, 0 deletions
diff --git a/gtk2_ardour/editor_imageframe.cc b/gtk2_ardour/editor_imageframe.cc
new file mode 100644
index 0000000000..57dbd0613e
--- /dev/null
+++ b/gtk2_ardour/editor_imageframe.cc
@@ -0,0 +1,1179 @@
+#include "imageframe_view.h"
+#include "imageframe_time_axis.h"
+#include "imageframe_time_axis_view.h"
+#include "imageframe_time_axis_group.h"
+#include "marker_time_axis_view.h"
+#include "marker_time_axis.h"
+#include "marker_view.h"
+#include "editor.h"
+#include "i18n.h"
+#include <gtkmmext/gtk_ui.h>
+#include <pbd/error.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <unistd.h>
+#include <arpa/inet.h>
+
+#include "imageframe_socket_handler.h"
+#include "ardour_image_compositor_socket.h"
+#include "public_editor.h"
+
+/* <CMT Additions file="editor.cc"> */
+
+void
+Editor::add_imageframe_time_axis(std::string track_name, void* src)
+{
+ // check for duplicate name
+ if(get_named_time_axis(track_name))
+ {
+ warning << "Repeated time axis name" << std::endl ;
+ }
+ else
+ {
+ Gtkmmext::UI::instance()->call_slot(bind(slot(*this, &Editor::handle_new_imageframe_time_axis_view),track_name, src)) ;
+ }
+}
+
+void
+Editor::connect_to_image_compositor()
+{
+ if(image_socket_listener == 0)
+ {
+ image_socket_listener = ImageFrameSocketHandler::create_instance(*this) ;
+ }
+
+ if(image_socket_listener->is_connected() == true)
+ {
+ return ;
+ }
+
+ // XXX should really put this somewhere safe
+ std::string host_ip = "127.0.0.1" ;
+
+ bool retcode = image_socket_listener->connect(host_ip,ardourvis::DEFAULT_PORT) ;
+
+ if(retcode == false)
+ {
+ // XXX need to get some return status here
+ warning << "Image Compositor Connection attempt failed" << std::endl ;
+ return ;
+ }
+
+ // add the socket to the gui loop, and keep the retuned tag value of the input
+ gint tag = gdk_input_add(image_socket_listener->get_socket_descriptor(), GDK_INPUT_READ,ImageFrameSocketHandler::image_socket_callback,image_socket_listener) ;
+ image_socket_listener->set_gdk_input_tag(tag) ;
+}
+
+void
+Editor::scroll_timeaxis_to_imageframe_item(const TimeAxisViewItem* item)
+{
+ jack_nframes_t offset = static_cast<jack_nframes_t>(frames_per_unit * (edit_hscroll_slider_width/2)) ;
+
+ jack_nframes_t x_pos = 0 ;
+ if(item->get_position() < offset)
+ {
+ x_pos = 0 ;
+ }
+ else
+ {
+ x_pos = item->get_position() - offset + (item->get_duration() / 2) ;
+ }
+
+ reposition_x_origin(x_pos) ;
+}
+
+void
+Editor::add_imageframe_marker_time_axis(std::string track_name, TimeAxisView* marked_track, void* src)
+{
+ // Can we only bind 2 data Items?
+ // @todo we really want to bind the src attribute too, for the moment tracks can only be added remotely,
+ // so this is not too much of an issue, however will need to be looked at again
+ Gtkmmext::UI::instance()->call_slot(SigC::bind(slot(*this, &Editor::handle_new_imageframe_marker_time_axis_view),track_name, marked_track)) ;
+}
+
+void
+Editor::popup_imageframe_edit_menu(int button, int32_t time, GtkCanvasItem* ifv, bool with_item)
+{
+ ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(clicked_trackview) ;
+
+ if(ifta)
+ {
+ ImageFrameTimeAxisGroup* iftag = ifta->get_view()->get_selected_imageframe_group() ;
+
+ if(iftag)
+ {
+ ImageFrameView* selected_ifv = ifta->get_view()->get_selected_imageframe_view() ;
+ ifta->popup_imageframe_edit_menu(button, time, selected_ifv, with_item) ;
+ }
+ }
+}
+
+void
+Editor::popup_marker_time_axis_edit_menu(int button, int32_t time, GtkCanvasItem* ifv, bool with_item)
+{
+ MarkerTimeAxis* mta = dynamic_cast<MarkerTimeAxis*>(clicked_trackview) ;
+
+ if(mta)
+ {
+ MarkerView* selected_mv = mta->get_view()->get_selected_time_axis_item() ;
+ if(selected_mv)
+ {
+ mta->popup_marker_time_axis_edit_menu(button,time, selected_mv, with_item) ;
+ }
+ }
+}
+
+TimeAxisView*
+Editor::get_named_time_axis(std::string name)
+{
+ TimeAxisView* tav = 0 ;
+
+ for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i)
+ {
+ if (((TimeAxisView*)*i)->name() == name)
+ {
+ tav = ((TimeAxisView*)*i) ;
+ break ;
+ }
+ }
+ return(tav) ;
+}
+
+/* </CMT Additions file="editor.cc"> */
+
+
+
+
+
+
+/* <CMT Additions file="editor_canvas_events.cc"> */
+
+/**
+ * ---------------------------------------------------------------------------------------------------
+ * Static event handlers
+ * These handlers deal with events from the GtkCanvas, a c-based component
+ */
+
+
+gint
+Editor::_canvas_imageframe_start_handle_event(GtkCanvasItem *item, GdkEvent *event, gpointer data)
+{
+ ImageFrameView* ifv = (ImageFrameView*) data ;
+ Editor* editor = dynamic_cast<Editor*> (&ifv->get_time_axis_view().editor);
+ return editor->canvas_imageframe_start_handle_event(item,event,ifv);
+}
+
+gint
+Editor::_canvas_imageframe_end_handle_event(GtkCanvasItem *item, GdkEvent *event, gpointer data)
+{
+ ImageFrameView* ifv = (ImageFrameView*) data ;
+ Editor* editor = dynamic_cast<Editor*> (&ifv->get_time_axis_view().editor);
+ return editor->canvas_imageframe_end_handle_event(item,event,ifv);
+}
+
+
+gint
+Editor::_canvas_imageframe_item_view_event(GtkCanvasItem *item, GdkEvent* event, gpointer data)
+{
+ ImageFrameView *ifv = (ImageFrameView *) data ;
+ Editor* editor = dynamic_cast<Editor*> (&ifv->get_time_axis_view().editor);
+ return editor->canvas_imageframe_item_view_event (item, event, ifv) ;
+}
+
+gint
+Editor::_canvas_imageframe_view_event(GtkCanvasItem *item, GdkEvent* event, gpointer data)
+{
+ ImageFrameTimeAxis *ifta = (ImageFrameTimeAxis*) data ;
+ Editor* editor = dynamic_cast<Editor*> (&ifta->editor);
+ return editor->canvas_imageframe_view_event (item, event, ifta);
+}
+
+gint
+Editor::_canvas_marker_time_axis_view_event(GtkCanvasItem* item, GdkEvent* event, gpointer data)
+{
+ MarkerTimeAxis* mta = (MarkerTimeAxis*)data ;
+ Editor* editor = dynamic_cast<Editor*> (&mta->editor);
+ return editor->canvas_marker_time_axis_view_event(item,event,mta);
+}
+
+gint
+Editor::_canvas_markerview_item_view_event(GtkCanvasItem *item, GdkEvent* event, gpointer data)
+{
+ MarkerView* mv = (MarkerView*) data ;
+ Editor* editor = dynamic_cast<Editor*> (&mv->get_time_axis_view().editor);
+ return editor->canvas_markerview_item_view_event(item,event,mv);
+}
+
+gint
+Editor::_canvas_markerview_start_handle_event(GtkCanvasItem* item, GdkEvent* event, gpointer data)
+{
+ MarkerView* mv = (MarkerView*)data ;
+ Editor* editor = dynamic_cast<Editor*> (&mv->get_time_axis_view().editor);
+ return editor->canvas_markerview_start_handle_event(item,event,mv);
+}
+
+gint
+Editor::_canvas_markerview_end_handle_event(GtkCanvasItem* item, GdkEvent* event, gpointer data)
+{
+ MarkerView* mv = (MarkerView*)data ;
+ Editor* editor = dynamic_cast<Editor*> (&mv->get_time_axis_view().editor);
+ return editor->canvas_markerview_end_handle_event(item,event,mv);
+}
+
+/**
+ * ---------------------------------------------------------------------------------------------------
+ * End of Static event handlers
+ */
+
+gint
+Editor::canvas_imageframe_item_view_event(GtkCanvasItem *item, GdkEvent *event, ImageFrameView *ifv)
+{
+ gint ret = FALSE ;
+ ImageFrameTimeAxisGroup* iftag = 0 ;
+
+ switch (event->type)
+ {
+ case GDK_BUTTON_PRESS:
+ case GDK_2BUTTON_PRESS:
+ case GDK_3BUTTON_PRESS:
+ clicked_trackview = &ifv->get_time_axis_view();
+ iftag = ifv->get_time_axis_group() ;
+ dynamic_cast<ImageFrameTimeAxis*>(clicked_trackview)->get_view()->set_selected_imageframe_view(iftag, ifv);
+ ret = button_press_handler (item, event, ImageFrameItem) ;
+ break ;
+ case GDK_BUTTON_RELEASE:
+ ret = button_release_handler (item, event, ImageFrameItem) ;
+ break ;
+ case GDK_MOTION_NOTIFY:
+ ret = motion_handler (item, event, ImageFrameItem) ;
+ break ;
+ default:
+ break ;
+ }
+ return(ret) ;
+}
+
+gint
+Editor::canvas_imageframe_start_handle_event(GtkCanvasItem *item, GdkEvent *event, ImageFrameView *ifv)
+{
+ gint ret = FALSE ;
+ ImageFrameTimeAxisGroup* iftag = 0 ;
+
+ switch (event->type)
+ {
+ case GDK_BUTTON_PRESS:
+ case GDK_2BUTTON_PRESS:
+ case GDK_3BUTTON_PRESS:
+ clicked_trackview = &ifv->get_time_axis_view() ;
+ iftag = ifv->get_time_axis_group() ;
+ dynamic_cast<ImageFrameTimeAxis*>(clicked_trackview)->get_view()->set_selected_imageframe_view(iftag, ifv);
+
+ ret = button_press_handler (item, event, ImageFrameHandleStartItem) ;
+ break ;
+ case GDK_BUTTON_RELEASE:
+ ret = button_release_handler (item, event, ImageFrameHandleStartItem) ;
+ break;
+ case GDK_MOTION_NOTIFY:
+ ret = motion_handler (item, event, ImageFrameHandleStartItem) ;
+ break ;
+ case GDK_ENTER_NOTIFY:
+ ret = enter_handler (item, event, ImageFrameHandleStartItem) ;
+ break ;
+ case GDK_LEAVE_NOTIFY:
+ ret = leave_handler (item, event, ImageFrameHandleStartItem) ;
+ break ;
+ default:
+ break ;
+ }
+ return(ret) ;
+}
+
+gint
+Editor::canvas_imageframe_end_handle_event(GtkCanvasItem *item, GdkEvent *event, ImageFrameView *ifv)
+{
+ gint ret = FALSE ;
+ ImageFrameTimeAxisGroup* iftag = 0 ;
+
+ switch (event->type)
+ {
+ case GDK_BUTTON_PRESS:
+ case GDK_2BUTTON_PRESS:
+ case GDK_3BUTTON_PRESS:
+ clicked_trackview = &ifv->get_time_axis_view() ;
+ iftag = ifv->get_time_axis_group() ;
+ dynamic_cast<ImageFrameTimeAxis*>(clicked_trackview)->get_view()->set_selected_imageframe_view(iftag, ifv);
+
+ ret = button_press_handler (item, event, ImageFrameHandleEndItem) ;
+ break ;
+ case GDK_BUTTON_RELEASE:
+ ret = button_release_handler (item, event, ImageFrameHandleEndItem) ;
+ break ;
+ case GDK_MOTION_NOTIFY:
+ ret = motion_handler (item, event, ImageFrameHandleEndItem) ;
+ break ;
+ case GDK_ENTER_NOTIFY:
+ ret = enter_handler (item, event, ImageFrameHandleEndItem) ;
+ break ;
+ case GDK_LEAVE_NOTIFY:
+ ret = leave_handler (item, event, ImageFrameHandleEndItem);
+ break ;
+ default:
+ break ;
+ }
+ return(ret) ;
+}
+
+gint
+Editor::canvas_imageframe_view_event(GtkCanvasItem* item, GdkEvent* event, ImageFrameTimeAxis* ifta)
+{
+ gint ret = FALSE ;
+ switch (event->type)
+ {
+ case GDK_BUTTON_PRESS:
+ case GDK_2BUTTON_PRESS:
+ case GDK_3BUTTON_PRESS:
+ clicked_trackview = ifta ;
+ ret = button_press_handler (item, event, ImageFrameTimeAxisItem) ;
+ break ;
+ case GDK_BUTTON_RELEASE:
+ ret = button_release_handler (item, event, ImageFrameTimeAxisItem) ;
+ break ;
+ case GDK_MOTION_NOTIFY:
+ break ;
+ default:
+ break ;
+ }
+ return(ret) ;
+}
+
+gint
+Editor::canvas_marker_time_axis_view_event(GtkCanvasItem *item, GdkEvent* event, MarkerTimeAxis* mta)
+{
+ gint ret = FALSE ;
+ switch (event->type)
+ {
+ case GDK_BUTTON_PRESS:
+ case GDK_2BUTTON_PRESS:
+ case GDK_3BUTTON_PRESS:
+ clicked_trackview = mta ;
+ ret = button_press_handler(item, event, MarkerTimeAxisItem) ;
+ break ;
+ case GDK_BUTTON_RELEASE:
+ ret = button_release_handler(item, event, MarkerTimeAxisItem) ;
+ break ;
+ case GDK_MOTION_NOTIFY:
+ default:
+ break ;
+ }
+ return(ret) ;
+}
+
+
+gint
+Editor::canvas_markerview_item_view_event(GtkCanvasItem *item, GdkEvent* event, MarkerView* mta)
+{
+ gint ret = FALSE ;
+ switch (event->type)
+ {
+ case GDK_BUTTON_PRESS:
+ case GDK_2BUTTON_PRESS:
+ case GDK_3BUTTON_PRESS:
+ clicked_trackview = &mta->get_time_axis_view() ;
+ dynamic_cast<MarkerTimeAxis*>(clicked_trackview)->get_view()->set_selected_time_axis_item(mta);
+ ret = button_press_handler(item, event, MarkerViewItem) ;
+ break ;
+ case GDK_BUTTON_RELEASE:
+ ret = button_release_handler(item, event, MarkerViewItem) ;
+ break ;
+ case GDK_MOTION_NOTIFY:
+ ret = motion_handler(item, event, MarkerViewItem) ;
+ break ;
+ default:
+ break ;
+ }
+ return(ret) ;
+}
+
+gint
+Editor::canvas_markerview_start_handle_event(GtkCanvasItem* item, GdkEvent* event, MarkerView* mta)
+{
+ gint ret = FALSE ;
+ switch (event->type)
+ {
+ case GDK_BUTTON_PRESS:
+ case GDK_2BUTTON_PRESS:
+ case GDK_3BUTTON_PRESS:
+ clicked_trackview = &mta->get_time_axis_view() ;
+ dynamic_cast<MarkerTimeAxis*>(clicked_trackview)->get_view()->set_selected_time_axis_item(mta) ;
+ ret = button_press_handler(item, event, MarkerViewHandleStartItem) ;
+ break ;
+ case GDK_BUTTON_RELEASE:
+ ret = button_release_handler(item, event, MarkerViewHandleStartItem) ;
+ break ;
+ case GDK_MOTION_NOTIFY:
+ ret = motion_handler(item, event, MarkerViewHandleStartItem) ;
+ break ;
+ case GDK_ENTER_NOTIFY:
+ ret = enter_handler(item, event, MarkerViewHandleStartItem) ;
+ break ;
+ case GDK_LEAVE_NOTIFY:
+ ret = leave_handler(item, event, MarkerViewHandleStartItem) ;
+ break ;
+ default:
+ break ;
+ }
+ return(ret) ;
+}
+
+gint
+Editor::canvas_markerview_end_handle_event(GtkCanvasItem* item, GdkEvent* event, MarkerView* mta)
+{
+ gint ret = FALSE ;
+ switch (event->type)
+ {
+ case GDK_BUTTON_PRESS:
+ case GDK_2BUTTON_PRESS:
+ case GDK_3BUTTON_PRESS:
+ clicked_trackview = &mta->get_time_axis_view() ;
+ dynamic_cast<MarkerTimeAxis*>(clicked_trackview)->get_view()->set_selected_time_axis_item(mta) ;
+ ret = button_press_handler(item, event, MarkerViewHandleEndItem) ;
+ break ;
+ case GDK_BUTTON_RELEASE:
+ ret = button_release_handler(item, event, MarkerViewHandleEndItem) ;
+ break ;
+ case GDK_MOTION_NOTIFY:
+ ret = motion_handler(item, event, MarkerViewHandleEndItem) ;
+ break ;
+ case GDK_ENTER_NOTIFY:
+ ret = enter_handler(item, event, MarkerViewHandleEndItem) ;
+ break ;
+ case GDK_LEAVE_NOTIFY:
+ ret = leave_handler(item, event, MarkerViewHandleEndItem) ;
+ break ;
+ default:
+ break ;
+ }
+ return(ret) ;
+}
+
+
+/* </CMT Additions file="editor_canvas_events.cc"> */
+
+
+/*
+ ---------------------------------------------------------------------------------------------------
+ ---------------------------------------------------------------------------------------------------
+ ---------------------------------------------------------------------------------------------------
+*/
+
+
+
+/* <CMT Additions file="editor_mouse.cc"> */
+
+void
+Editor::start_imageframe_grab(GtkCanvasItem* item, GdkEvent* event)
+{
+ ImageFrameView* ifv = ((ImageFrameTimeAxis*)clicked_trackview)->get_view()->get_selected_imageframe_view() ;
+ drag_info.copy = false ;
+ drag_info.item = item ;
+ drag_info.data = ifv ;
+ drag_info.motion_callback = &Editor::imageframe_drag_motion_callback;
+ drag_info.finished_callback = &Editor::timeaxis_item_drag_finished_callback;
+ drag_info.last_frame_position = ifv->get_position() ;
+
+ drag_info.last_trackview = &ifv->get_time_axis_view() ;
+
+ /* this is subtle. raising the regionview itself won't help,
+ because raise_to_top() just puts the item on the top of
+ its parent's stack. so, we need to put the trackview canvas_display group
+ on the top, since its parent is the whole canvas.
+
+ however, this hides the measure bars within that particular trackview,
+ so move them to the top afterwards.
+ */
+
+ gtk_canvas_item_raise_to_top(drag_info.item) ;
+ gtk_canvas_item_raise_to_top(drag_info.last_trackview->canvas_display) ;
+ //gtk_canvas_item_raise_to_top(time_line_group) ;
+ gtk_canvas_item_raise_to_top (cursor_group);
+
+ start_grab(event) ;
+
+ drag_info.pointer_frame_offset = pixel_to_frame(drag_info.grab_x) - drag_info.last_frame_position;
+}
+
+
+void
+Editor::start_markerview_grab(GtkCanvasItem* item, GdkEvent* event)
+{
+ MarkerView* mv = ((MarkerTimeAxis*)clicked_trackview)->get_view()->get_selected_time_axis_item() ;
+ drag_info.copy = false ;
+ drag_info.item = item ;
+ drag_info.data = mv ;
+ drag_info.motion_callback = &Editor::markerview_drag_motion_callback;
+ drag_info.finished_callback = &Editor::timeaxis_item_drag_finished_callback;
+ drag_info.last_frame_position = mv->get_position() ;
+
+ drag_info.last_trackview = &mv->get_time_axis_view() ;
+
+ /* this is subtle. raising the regionview itself won't help,
+ because raise_to_top() just puts the item on the top of
+ its parent's stack. so, we need to put the trackview canvas_display group
+ on the top, since its parent is the whole canvas.
+
+ however, this hides the measure bars within that particular trackview,
+ so move them to the top afterwards.
+ */
+
+ gtk_canvas_item_raise_to_top(drag_info.item) ;
+ gtk_canvas_item_raise_to_top(drag_info.last_trackview->canvas_display) ;
+ //gtk_canvas_item_raise_to_top(time_line_group) ;
+ gtk_canvas_item_raise_to_top (cursor_group);
+
+ start_grab(event) ;
+
+ drag_info.pointer_frame_offset = pixel_to_frame(drag_info.grab_x) - drag_info.last_frame_position ;
+}
+
+
+void
+Editor::markerview_drag_motion_callback(GtkCanvasItem*, GdkEvent* event)
+{
+ double cx, cy ;
+
+ MarkerView* mv = reinterpret_cast<MarkerView*>(drag_info.data) ;
+ jack_nframes_t pending_region_position ;
+ jack_nframes_t pointer_frame ;
+
+ pointer_frame = event_frame(event, &cx, &cy) ;
+
+ snap_to(pointer_frame) ;
+
+ if (pointer_frame > (jack_nframes_t) drag_info.pointer_frame_offset)
+ {
+ pending_region_position = pointer_frame - drag_info.pointer_frame_offset ;
+ snap_to(pending_region_position) ;
+
+ // we dont allow marker items to extend beyond, or in front of the marked items so
+ // cap the value to the marked items position and duration
+ if((pending_region_position + mv->get_duration()) >= ((mv->get_marked_item()->get_position()) + (mv->get_marked_item()->get_duration())))
+ {
+ pending_region_position = (mv->get_marked_item()->get_position() + mv->get_marked_item()->get_duration()) - (mv->get_duration()) ;
+ }
+ else if(pending_region_position <= mv->get_marked_item()->get_position())
+ {
+ pending_region_position = mv->get_marked_item()->get_position() ;
+ }
+ }
+ else
+ {
+ pending_region_position = mv->get_marked_item()->get_position() ;
+ }
+
+ drag_info.last_frame_position = pending_region_position ;
+
+ // we treat this as a special case, usually we want to send the identitiy of the caller
+ // but in this case, that would trigger our socket handler to handle the event, sending
+ // notification to the image compositor. This would be fine, except that we have not
+ // finished the drag, we therefore do not want to sent notification until we have
+ // completed the drag, only then do we want the image compositor notofied.
+ // We therefore set the caller identity to the special case of 0
+ mv->set_position(pending_region_position, 0) ;
+
+ show_verbose_time_cursor(pending_region_position) ;
+}
+
+void
+Editor::imageframe_drag_motion_callback(GtkCanvasItem*, GdkEvent* event)
+{
+ double cx, cy ;
+
+ ImageFrameView* ifv = reinterpret_cast<ImageFrameView*>(drag_info.data) ;
+
+ jack_nframes_t pending_region_position;
+ jack_nframes_t pointer_frame;
+
+ pointer_frame = event_frame(event, &cx, &cy) ;
+
+ snap_to(pointer_frame) ;
+
+ if (pointer_frame > (jack_nframes_t) drag_info.pointer_frame_offset)
+ {
+ pending_region_position = pointer_frame - drag_info.pointer_frame_offset ;
+ snap_to(pending_region_position) ;
+ }
+ else
+ {
+ pending_region_position = 0 ;
+ }
+
+ drag_info.grab_x = cx;
+ //drag_info.last_frame_position = pending_region_position ;
+ drag_info.current_pointer_frame = pending_region_position ;
+
+ // we treat this as a special case, usually we want to send the identitiy of the caller
+ // but in this case, that would trigger our socket handler to handle the event, sending
+ // notification to the image compositor. This would be fine, except that we have not
+ // finished the drag, we therefore do not want to sent notification until we have
+ // completed the drag, only then do we want the image compositor notofied.
+ // We therefore set the caller identity to the special case of 0
+ ifv->set_position(pending_region_position, 0) ;
+
+ show_verbose_time_cursor(pending_region_position) ;
+}
+
+void
+Editor::timeaxis_item_drag_finished_callback(GtkCanvasItem*, GdkEvent* event)
+{
+ jack_nframes_t where ;
+ TimeAxisViewItem* tavi = reinterpret_cast<TimeAxisViewItem*>(drag_info.data) ;
+
+ bool item_x_movement = (drag_info.last_frame_position != tavi->get_position()) ;
+
+ hide_verbose_canvas_cursor() ;
+
+ /* no x or y movement either means the regionview hasn't been moved, or has been moved
+ but is back in it's original position/trackview.*/
+
+ if(!item_x_movement && event && event->type == GDK_BUTTON_RELEASE)
+ {
+ /* No motion: either set the current region, or align the clicked region
+ with the current one.
+ */
+ return;
+ }
+
+ if(item_x_movement)
+ {
+ /* base the new region position on the current position of the regionview.*/
+ where = drag_info.current_pointer_frame ;
+
+ // final call to set position after the motion to tell interested parties of the new position
+ tavi->set_position(where, this) ;
+ }
+ else
+ {
+ //where = tavi->get_position() ;
+ }
+
+
+}
+
+
+void
+Editor::imageframe_start_handle_op(GtkCanvasItem* item, GdkEvent* event)
+{
+ // get the selected item from the parent time axis
+ ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(clicked_trackview) ;
+ if(ifta)
+ {
+ ImageFrameView* ifv = ifta->get_view()->get_selected_imageframe_view() ;
+
+ if (ifv == 0) {
+ fatal << _("programming error: no ImageFrameView selected") << endmsg;
+ /*NOTREACHED*/
+ return ;
+ }
+
+ drag_info.item = ifv->get_canvas_frame() ;
+ drag_info.data = ifv;
+ drag_info.grab_x = event->motion.x;
+ drag_info.cumulative_x_drag = 0;
+ drag_info.motion_callback = &Editor::imageframe_start_handle_trim_motion ;
+ drag_info.finished_callback = &Editor::imageframe_start_handle_end_trim ;
+
+ flush_track_canvas() ;
+
+ start_grab(event) ;
+
+ show_verbose_time_cursor(ifv->get_position(), 10) ;
+ }
+}
+
+void
+Editor::imageframe_end_handle_op(GtkCanvasItem* item, GdkEvent* event)
+{
+ // get the selected item from the parent time axis
+ ImageFrameTimeAxis* ifta = dynamic_cast<ImageFrameTimeAxis*>(clicked_trackview) ;
+
+ if(ifta)
+ {
+ ImageFrameView* ifv = ifta->get_view()->get_selected_imageframe_view() ;
+
+ if (ifv == 0)
+ {
+ fatal << _("programming error: no ImageFrameView selected") << endmsg ;
+ /*NOTREACHED*/
+ return ;
+ }
+
+ drag_info.item = ifv->get_canvas_frame() ;
+ drag_info.data = ifv ;
+ drag_info.grab_x = event->motion.x ;
+ drag_info.cumulative_x_drag = 0 ;
+ drag_info.motion_callback = &Editor::imageframe_end_handle_trim_motion ;
+ drag_info.finished_callback = &Editor::imageframe_end_handle_end_trim ;
+
+ flush_track_canvas() ;
+
+ start_grab(event, trimmer_cursor) ;
+
+ show_verbose_time_cursor(ifv->get_position() + ifv->get_duration(), 10) ;
+ }
+}
+
+void
+Editor::imageframe_start_handle_trim_motion(GtkCanvasItem* item, GdkEvent* event)
+{
+ ImageFrameView* ifv = reinterpret_cast<ImageFrameView*> (drag_info.data) ;
+
+ jack_nframes_t start = 0 ;
+ jack_nframes_t end = 0 ;
+ jack_nframes_t pointer_frame = event_frame(event) ;
+
+ // chekc th eposition of the item is not locked
+ if(!ifv->get_position_locked()) {
+ snap_to(pointer_frame) ;
+
+ if(pointer_frame != drag_info.last_pointer_frame) {
+ start = ifv->get_position() ;
+ end = ifv->get_position() + ifv->get_duration() ;
+
+ if (pointer_frame > end) {
+ start = end ;
+ } else {
+ start = pointer_frame ;
+ }
+
+ // are we getting bigger or smaller?
+ jack_nframes_t new_dur_val = end - start ;
+
+ // start handle, so a smaller pointer frame increases our component size
+ if(pointer_frame <= drag_info.grab_frame)
+ {
+ if(ifv->get_max_duration_active() && (new_dur_val > ifv->get_max_duration()))
+ {
+ new_dur_val = ifv->get_max_duration() ;
+ start = end - new_dur_val ;
+ }
+ else
+ {
+ // current values are ok
+ }
+ }
+ else
+ {
+ if(ifv->get_min_duration_active() && (new_dur_val < ifv->get_min_duration()))
+ {
+ new_dur_val = ifv->get_min_duration() ;
+ start = end - new_dur_val ;
+ }
+ else
+ {
+ // current values are ok
+ }
+ }
+
+ drag_info.last_pointer_frame = pointer_frame ;
+
+ /* re-calculatethe duration and position of the imageframeview */
+ drag_info.cumulative_x_drag = new_dur_val ;
+
+ // we treat this as a special case, usually we want to send the identitiy of the caller
+ // but in this case, that would trigger our socket handler to handle the event, sending
+ // notification to the image compositor. This would be fine, except that we have not
+ // finished the drag, we therefore do not want to sent notification until we have
+ // completed the drag, only then do we want the image compositor notofied.
+ // We therefore set the caller identity to the special case of 0
+ ifv->set_duration(new_dur_val, 0) ;
+ ifv->set_position(start, 0) ;
+ }
+ }
+
+ show_verbose_time_cursor(start, 10) ;
+}
+
+void
+Editor::imageframe_start_handle_end_trim(GtkCanvasItem* item, GdkEvent* event)
+{
+ ImageFrameView* ifv = reinterpret_cast<ImageFrameView *> (drag_info.data) ;
+
+ if (drag_info.cumulative_x_drag == 0)
+ {
+ /* just a click */
+ }
+ else
+ {
+ jack_nframes_t temp = ifv->get_position() + ifv->get_duration() ;
+
+ ifv->set_position((jack_nframes_t) (temp - drag_info.cumulative_x_drag), this) ;
+ ifv->set_duration((jack_nframes_t) drag_info.cumulative_x_drag, this) ;
+ }
+
+ flush_track_canvas() ;
+}
+
+void
+Editor::imageframe_end_handle_trim_motion(GtkCanvasItem* item, GdkEvent* event)
+{
+ ImageFrameView* ifv = reinterpret_cast<ImageFrameView *> (drag_info.data) ;
+
+ jack_nframes_t start = 0 ;
+ jack_nframes_t end = 0 ;
+ jack_nframes_t pointer_frame = event_frame(event) ;
+ jack_nframes_t new_dur_val = 0 ;
+
+ snap_to(pointer_frame) ;
+
+ if (pointer_frame != drag_info.last_pointer_frame)
+ {
+ start = ifv->get_position() ;
+ end = ifv->get_position() + ifv->get_duration() ;
+ if (pointer_frame < start)
+ {
+ end = start ;
+ }
+ else
+ {
+ end = pointer_frame ;
+ }
+
+ new_dur_val = end - start ;
+
+ // are we getting bigger or smaller?
+ if(pointer_frame >= drag_info.last_pointer_frame)
+ {
+ if(ifv->get_max_duration_active() && (new_dur_val > ifv->get_max_duration()))
+ {
+ new_dur_val = ifv->get_max_duration() ;
+ }
+ }
+ else
+ {
+ if(ifv->get_min_duration_active() && (new_dur_val < ifv->get_min_duration()))
+ {
+ new_dur_val = ifv->get_min_duration() ;
+ }
+ }
+
+ drag_info.last_pointer_frame = pointer_frame ;
+ drag_info.cumulative_x_drag = new_dur_val ;
+
+ // we treat this as a special case, usually we want to send the identitiy of the caller
+ // but in this case, that would trigger our socket handler to handle the event, sending
+ // notification to the image compositor. This would be fine, except that we have not
+ // finished the drag, we therefore do not want to sent notification until we have
+ // completed the drag, only then do we want the image compositor notofied.
+ // We therefore set the caller identity to the special case of 0
+ ifv->set_duration(new_dur_val, 0) ;
+ }
+
+ show_verbose_time_cursor(new_dur_val, 10) ;
+}
+
+
+void
+Editor::imageframe_end_handle_end_trim (GtkCanvasItem* item, GdkEvent* event)
+{
+ ImageFrameView* ifv = reinterpret_cast<ImageFrameView *> (drag_info.data) ;
+
+ if (drag_info.cumulative_x_drag == 0)
+ {
+ /* just a click */
+ }
+ else
+ {
+ jack_nframes_t new_duration = (jack_nframes_t)drag_info.cumulative_x_drag ;
+ if((new_duration <= ifv->get_max_duration()) && (new_duration >= ifv->get_min_duration()))
+ {
+ ifv->set_duration(new_duration, this) ;
+ }
+ }
+
+ flush_track_canvas ();
+}
+
+
+void
+Editor::markerview_item_start_handle_op(GtkCanvasItem* item, GdkEvent* event)
+{
+ MarkerView* mv = reinterpret_cast<MarkerTimeAxis*>(clicked_trackview)->get_view()->get_selected_time_axis_item() ;
+
+ if (mv == 0)
+ {
+ fatal << _("programming error: no MarkerView selected") << endmsg ;
+ /*NOTREACHED*/
+ return ;
+ }
+
+ drag_info.item = mv->get_canvas_frame() ;
+ drag_info.data = mv;
+ drag_info.grab_x = event->motion.x;
+
+ drag_info.cumulative_x_drag = 0 ;
+ drag_info.motion_callback = &Editor::markerview_start_handle_trim_motion ;
+ drag_info.finished_callback = &Editor::markerview_start_handle_end_trim ;
+
+ flush_track_canvas() ;
+
+ start_grab(event, trimmer_cursor) ;
+}
+
+void
+Editor::markerview_item_end_handle_op(GtkCanvasItem* item, GdkEvent* event)
+{
+ MarkerView* mv = reinterpret_cast<MarkerTimeAxis*>(clicked_trackview)->get_view()->get_selected_time_axis_item() ;
+ if (mv == 0)
+ {
+ fatal << _("programming error: no MarkerView selected") << endmsg ;
+ /*NOTREACHED*/
+ return ;
+ }
+
+ drag_info.item = mv->get_canvas_frame() ;
+ drag_info.data = mv ;
+ drag_info.grab_x = event->motion.x ;
+ drag_info.cumulative_x_drag = 0 ;
+
+ drag_info.motion_callback = &Editor::markerview_end_handle_trim_motion ;
+ drag_info.finished_callback = &Editor::markerview_end_handle_end_trim ;
+
+ flush_track_canvas () ;
+
+ start_grab(event, trimmer_cursor) ;
+}
+
+
+void
+Editor::markerview_start_handle_trim_motion(GtkCanvasItem* item, GdkEvent* event)
+{
+ MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
+
+ jack_nframes_t start = 0 ;
+ jack_nframes_t end = 0 ;
+ jack_nframes_t pointer_frame = event_frame(event) ;
+
+ // chekc th eposition of the item is not locked
+ if(!mv->get_position_locked())
+ {
+ snap_to(pointer_frame) ;
+ if(pointer_frame != drag_info.last_pointer_frame)
+ {
+ start = mv->get_position() ;
+ end = mv->get_position() + mv->get_duration() ;
+
+ if (pointer_frame > end)
+ {
+ start = end ;
+ }
+ else
+ {
+ start = pointer_frame ;
+ }
+
+ // are we getting bigger or smaller?
+ jack_nframes_t new_dur_val = end - start ;
+
+ if(pointer_frame <= drag_info.grab_frame)
+ {
+ if(mv->get_max_duration_active() && (new_dur_val > mv->get_max_duration()))
+ {
+ new_dur_val = mv->get_max_duration() ;
+ start = end - new_dur_val ;
+ }
+ else
+ {
+ // current values are ok
+ }
+ }
+ else
+ {
+ if(mv->get_min_duration_active() && (new_dur_val < mv->get_min_duration()))
+ {
+ new_dur_val = mv->get_min_duration() ;
+ start = end - new_dur_val ;
+ }
+ else
+ {
+ // current values are ok
+ }
+ }
+
+ drag_info.last_pointer_frame = pointer_frame ;
+
+ /* re-calculatethe duration and position of the imageframeview */
+ drag_info.cumulative_x_drag = new_dur_val ;
+
+ // we treat this as a special case, usually we want to send the identitiy of the caller
+ // but in this case, that would trigger our socket handler to handle the event, sending
+ // notification to the image compositor. This would be fine, except that we have not
+ // finished the drag, we therefore do not want to sent notification until we have
+ // completed the drag, only then do we want the image compositor notofied.
+ // We therefore set the caller identity to the special case of 0
+ mv->set_duration(new_dur_val, 0) ;
+ mv->set_position(start, 0) ;
+ }
+ }
+
+ show_verbose_time_cursor(start, 10) ;
+}
+
+void
+Editor::markerview_start_handle_end_trim(GtkCanvasItem* item, GdkEvent* event)
+{
+ MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
+
+ if (drag_info.cumulative_x_drag == 0)
+ {
+ /* just a click */
+ }
+ else
+ {
+ jack_nframes_t temp = mv->get_position() + mv->get_duration() ;
+
+ mv->set_position((jack_nframes_t) (temp - drag_info.cumulative_x_drag), this) ;
+ mv->set_duration((jack_nframes_t) drag_info.cumulative_x_drag, this) ;
+ }
+
+ flush_track_canvas() ;
+}
+
+void
+Editor::markerview_end_handle_trim_motion(GtkCanvasItem* item, GdkEvent* event)
+{
+ MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
+
+ jack_nframes_t start = 0 ;
+ jack_nframes_t end = 0 ;
+ jack_nframes_t pointer_frame = event_frame(event) ;
+ jack_nframes_t new_dur_val = 0 ;
+
+ snap_to(pointer_frame) ;
+
+ if (pointer_frame != drag_info.last_pointer_frame)
+ {
+ start = mv->get_position() ;
+ end = mv->get_position() + mv->get_duration() ;
+
+ if(pointer_frame < start)
+ {
+ end = start ;
+ }
+ else
+ {
+ end = pointer_frame ;
+ }
+
+ new_dur_val = end - start ;
+
+ // are we getting bigger or smaller?
+ if(pointer_frame >= drag_info.last_pointer_frame)
+ {
+ // we cant extend beyond the item we are marking
+ ImageFrameView* marked_item = mv->get_marked_item() ;
+ jack_nframes_t marked_end = marked_item->get_position() + marked_item->get_duration() ;
+
+ if(mv->get_max_duration_active() && (new_dur_val > mv->get_max_duration()))
+ {
+ if((start + mv->get_max_duration()) > marked_end)
+ {
+ new_dur_val = marked_end - start ;
+ }
+ else
+ {
+ new_dur_val = mv->get_max_duration() ;
+ }
+ }
+ else if(end > marked_end)
+ {
+ new_dur_val = marked_end - start ;
+ }
+ }
+ else
+ {
+ if(mv->get_min_duration_active() && (new_dur_val < mv->get_min_duration()))
+ {
+ new_dur_val = mv->get_min_duration() ;
+ }
+ }
+
+
+ drag_info.last_pointer_frame = pointer_frame ;
+ drag_info.cumulative_x_drag = new_dur_val ;
+
+ // we treat this as a special case, usually we want to send the identitiy of the caller
+ // but in this case, that would trigger our socket handler to handle the event, sending
+ // notification to the image compositor. This would be fine, except that we have not
+ // finished the drag, we therefore do not want to sent notification until we have
+ // completed the drag, only then do we want the image compositor notofied.
+ // We therefore set the caller identity to the special case of 0
+ mv->set_duration(new_dur_val, 0) ;
+ }
+
+ show_verbose_time_cursor(new_dur_val, 10) ;
+}
+
+
+void
+Editor::markerview_end_handle_end_trim (GtkCanvasItem* item, GdkEvent* event)
+{
+ MarkerView* mv = reinterpret_cast<MarkerView*> (drag_info.data) ;
+
+ if (drag_info.cumulative_x_drag == 0)
+ {
+ /* just a click */
+ }
+ else
+ {
+ jack_nframes_t new_duration = (jack_nframes_t)drag_info.cumulative_x_drag ;
+ mv->set_duration(new_duration, this) ;
+ }
+
+ flush_track_canvas() ;
+}
+
+
+/* </CMT Additions file="editor_mouse.cc"> */
+
+
+
+
+
+
+
+/* <CMT Additions file="editor_route_list.cc"> */
+
+void
+Editor::handle_new_imageframe_time_axis_view(std::string track_name, void* src)
+{
+ ImageFrameTimeAxis* iftav ;
+ iftav = new ImageFrameTimeAxis(track_name, *this, *session, track_canvas) ;
+ iftav->set_time_axis_name(track_name, this) ;
+ track_views.push_back(iftav) ;
+ const gchar *rowdata[1] ;
+ rowdata[0] = iftav->name().c_str() ;
+ route_list.rows().push_back(rowdata) ;
+ route_list.rows().back().set_data(iftav) ;
+ route_list.rows().back().select() ;
+ iftav->GoingAway.connect(bind(slot(*this, &Editor::remove_route), (TimeAxisView*)iftav)) ;
+ iftav->gui_changed.connect(slot(*this, &Editor::handle_gui_changes)) ;
+}
+
+void
+Editor::handle_new_imageframe_marker_time_axis_view(std::string track_name, TimeAxisView* marked_track)
+{
+ MarkerTimeAxis* mta = new MarkerTimeAxis (*this, *this->current_session(), track_canvas, track_name, marked_track) ;
+ ((ImageFrameTimeAxis*)marked_track)->add_marker_time_axis(mta, this) ;
+ track_views.push_back(mta) ;
+ const gchar *rowdata[1] ;
+ rowdata[0] = mta->name().c_str() ;
+ route_list.rows().push_back(rowdata) ;
+ route_list.rows().back().set_data (mta) ;
+ route_list.rows().back().select() ;
+ mta->GoingAway.connect(bind(slot (*this, &Editor::remove_route), (TimeAxisView*)mta)) ;
+ }
+
+
+/* </CMT Additions file="editor_route_list.cc"> */