X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_canvas_events.cc;h=34a73d318c029f79d4a1489e7cfef7274130b1d6;hb=035de2a367acd7ee27c3dbfba2f6c71f3c137eb8;hp=a7fbdec926991c9b07d8abb3e9b911fe3fa81410;hpb=7ccc494c37623d1c937e18510b1217f927f85760;p=ardour.git diff --git a/gtk2_ardour/editor_canvas_events.cc b/gtk2_ardour/editor_canvas_events.cc index a7fbdec926..34a73d318c 100644 --- a/gtk2_ardour/editor_canvas_events.cc +++ b/gtk2_ardour/editor_canvas_events.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2000 Paul Davis + Copyright (C) 2000 Paul Davis This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -24,17 +24,17 @@ #include "pbd/stacktrace.h" -#include "ardour/audio_diskstream.h" #include "ardour/audioplaylist.h" -#include "ardour/midi_region.h" #include "ardour/audioregion.h" #include "ardour/region_factory.h" +#include "ardour/midi_region.h" #include "editor.h" #include "keyboard.h" #include "public_editor.h" #include "audio_region_view.h" #include "audio_streamview.h" +#include "canvas-noevent-text.h" #include "crossfade_view.h" #include "audio_time_axis.h" #include "region_gain_line.h" @@ -44,60 +44,38 @@ #include "control_point.h" #include "canvas_impl.h" #include "simplerect.h" -#include "interactive-item.h" #include "editor_drag.h" #include "midi_time_axis.h" +#include "editor_regions.h" #include "i18n.h" -using namespace sigc; using namespace std; using namespace ARDOUR; using namespace PBD; using namespace Gtk; using namespace ArdourCanvas; +using Gtkmm2ext::Keyboard; + bool Editor::track_canvas_scroll (GdkEventScroll* ev) { - int x, y; - double wx, wy; nframes64_t xdelta; int direction = ev->direction; - - Gnome::Canvas::Item* item = track_canvas->get_item_at(ev->x, ev->y); - InteractiveItem* interactive_item = dynamic_cast(item); - if (interactive_item) { - return interactive_item->on_event(reinterpret_cast(ev)); - } retry: switch (direction) { case GDK_SCROLL_UP: if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { - //if (ev->state == GDK_CONTROL_MASK) { - /* XXX - the ev->x will be out of step with the canvas - if we're in mid zoom, so we have to get the damn mouse - pointer again - */ - track_canvas->get_pointer (x, y); - track_canvas->window_to_world (x, y, wx, wy); - - GdkEvent event; - event.type = GDK_BUTTON_RELEASE; - event.button.x = wx; - event.button.y = wy; - - nframes64_t where = event_frame (&event, 0, 0); - temporal_zoom_to_frame (false, where); + temporal_zoom_step (false); return true; } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) { direction = GDK_SCROLL_LEFT; goto retry; } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) { if (!current_stepping_trackview) { - step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500); + step_timeout = Glib::signal_timeout().connect (sigc::mem_fun(*this, &Editor::track_height_step_timeout), 500); std::pair const p = trackview_by_y_position (ev->y + vertical_adjustment.get_value() - canvas_timebars_vsize); current_stepping_trackview = p.first; if (!current_stepping_trackview) { @@ -115,24 +93,14 @@ Editor::track_canvas_scroll (GdkEventScroll* ev) case GDK_SCROLL_DOWN: if (Keyboard::modifier_state_equals (ev->state, Keyboard::PrimaryModifier)) { - //if (ev->state == GDK_CONTROL_MASK) { - track_canvas->get_pointer (x, y); - track_canvas->window_to_world (x, y, wx, wy); - - GdkEvent event; - event.type = GDK_BUTTON_RELEASE; - event.button.x = wx; - event.button.y = wy; - - nframes64_t where = event_frame (&event, 0, 0); - temporal_zoom_to_frame (true, where); + temporal_zoom_step (true); return true; } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::SecondaryModifier)) { direction = GDK_SCROLL_RIGHT; goto retry; } else if (Keyboard::modifier_state_equals (ev->state, Keyboard::TertiaryModifier)) { if (!current_stepping_trackview) { - step_timeout = Glib::signal_timeout().connect (mem_fun(*this, &Editor::track_height_step_timeout), 500); + step_timeout = Glib::signal_timeout().connect (sigc::mem_fun(*this, &Editor::track_height_step_timeout), 500); std::pair const p = trackview_by_y_position (ev->y + vertical_adjustment.get_value() - canvas_timebars_vsize); current_stepping_trackview = p.first; if (!current_stepping_trackview) { @@ -146,7 +114,7 @@ Editor::track_canvas_scroll (GdkEventScroll* ev) scroll_tracks_down_line (); return true; } - break; + break; case GDK_SCROLL_LEFT: xdelta = (current_page_frames() / 8); @@ -178,12 +146,11 @@ bool Editor::track_canvas_scroll_event (GdkEventScroll *event) { track_canvas->grab_focus(); - track_canvas_scroll (event); - return false; + return track_canvas_scroll (event); } bool -Editor::track_canvas_button_press_event (GdkEventButton *event) +Editor::track_canvas_button_press_event (GdkEventButton */*event*/) { selection->clear (); track_canvas->grab_focus(); @@ -193,16 +160,14 @@ Editor::track_canvas_button_press_event (GdkEventButton *event) bool Editor::track_canvas_button_release_event (GdkEventButton *event) { - if (_drag) { - _drag->end_grab ((GdkEvent*) event); - delete _drag; - _drag = 0; + if (_drags->active ()) { + _drags->end_grab ((GdkEvent*) event); } return false; } bool -Editor::track_canvas_motion_notify_event (GdkEventMotion *event) +Editor::track_canvas_motion_notify_event (GdkEventMotion */*event*/) { int x, y; /* keep those motion events coming */ @@ -225,7 +190,7 @@ bool Editor::typed_event (ArdourCanvas::Item* item, GdkEvent *event, ItemType type) { gint ret = FALSE; - + switch (event->type) { case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: @@ -262,7 +227,6 @@ Editor::canvas_region_view_event (GdkEvent *event, ArdourCanvas::Item* item, Reg return false; } - switch (event->type) { case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: @@ -303,7 +267,7 @@ bool Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, RouteTimeAxisView *tv) { bool ret = FALSE; - + switch (event->type) { case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: @@ -320,7 +284,7 @@ Editor::canvas_stream_view_event (GdkEvent *event, ArdourCanvas::Item* item, Rou break; case GDK_MOTION_NOTIFY: - ret = motion_handler (item, event, StreamItem); + ret = motion_handler (item, event); break; case GDK_ENTER_NOTIFY: @@ -405,11 +369,11 @@ Editor::canvas_fade_in_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRe default: break; - + } /* proxy for the regionview */ - + return canvas_region_view_event (event, rv->get_canvas_group(), rv); } @@ -417,7 +381,7 @@ bool Editor::canvas_fade_in_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv) { bool ret = false; - + if (!rv->sensitive()) { return false; } @@ -442,10 +406,12 @@ Editor::canvas_fade_in_handle_event (GdkEvent *event, ArdourCanvas::Item* item, break; case GDK_ENTER_NOTIFY: + set_entered_regionview (rv); ret = enter_handler (item, event, FadeInHandleItem); break; case GDK_LEAVE_NOTIFY: + set_entered_regionview (0); ret = leave_handler (item, event, FadeInHandleItem); break; @@ -484,11 +450,11 @@ Editor::canvas_fade_out_event (GdkEvent *event, ArdourCanvas::Item* item, AudioR default: break; - + } /* proxy for the regionview */ - + return canvas_region_view_event (event, rv->get_canvas_group(), rv); } @@ -496,7 +462,7 @@ bool Editor::canvas_fade_out_handle_event (GdkEvent *event, ArdourCanvas::Item* item, AudioRegionView *rv) { bool ret = false; - + if (!rv->sensitive()) { return false; } @@ -521,10 +487,12 @@ Editor::canvas_fade_out_handle_event (GdkEvent *event, ArdourCanvas::Item* item, break; case GDK_ENTER_NOTIFY: + set_entered_regionview (rv); ret = enter_handler (item, event, FadeOutHandleItem); break; case GDK_LEAVE_NOTIFY: + set_entered_regionview (0); ret = leave_handler (item, event, FadeOutHandleItem); break; @@ -552,7 +520,7 @@ Editor::canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item* item, clicked_axisview = &clicked_crossfadeview->get_time_axis_view(); if (event->button.button == 3) { return button_press_handler (item, event, CrossfadeViewItem); - } + } break; case GDK_BUTTON_RELEASE: @@ -564,7 +532,7 @@ Editor::canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item* item, default: break; - + } /* XXX do not forward double clicks */ @@ -572,13 +540,13 @@ Editor::canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item* item, if (event->type == GDK_2BUTTON_PRESS) { return false; } - - /* proxy for the upper most regionview */ + + /* proxy for an underlying regionview */ /* XXX really need to check if we are in the name highlight, and proxy to that when required. */ - + TimeAxisView& tv (xfv->get_time_axis_view()); AudioTimeAxisView* atv; @@ -587,22 +555,57 @@ Editor::canvas_crossfade_view_event (GdkEvent* event, ArdourCanvas::Item* item, if (atv->is_audio_track()) { boost::shared_ptr pl; - if ((pl = boost::dynamic_pointer_cast (atv->get_diskstream()->playlist())) != 0) { + if ((pl = boost::dynamic_pointer_cast (atv->track()->playlist())) != 0) { Playlist::RegionList* rl = pl->regions_at (event_frame (event)); - if (!rl->empty()) { - DescendingRegionLayerSorter cmp; - rl->sort (cmp); - RegionView* rv = atv->view()->find_view (rl->front()); + if (atv->layer_display() == Overlaid) { + + /* we're in overlaid mode; proxy to the uppermost region view */ + + DescendingRegionLayerSorter cmp; + rl->sort (cmp); + + RegionView* rv = atv->view()->find_view (rl->front()); + + delete rl; + + /* proxy */ + return canvas_region_view_event (event, rv->get_canvas_group(), rv); + + } else { + + /* we're in stacked mode; proxy to the region view under the mouse */ + + /* XXX: FIXME: this is an evil hack; it assumes that any event for which + this proxy is being used has its GdkEvent laid out such that the y + member is in the same place as that for a GdkEventButton */ + + /* position of the event within the track */ + double cx = event->button.x; + double cy = event->button.y; + atv->view()->canvas_item()->w2i (cx, cy); - delete rl; + /* hence layer that we're over */ + double const c = atv->view()->child_height (); + layer_t const l = pl->top_layer () + 1 - (cy / c); - /* proxy */ - - return canvas_region_view_event (event, rv->get_canvas_group(), rv); - } + /* hence region */ + Playlist::RegionList::iterator i = rl->begin(); + while (i != rl->end() && (*i)->layer() != l) { + ++i; + } + + if (i != rl->end()) { + RegionView* rv = atv->view()->find_view (*i); + delete rl; + + /* proxy */ + return canvas_region_view_event (event, rv->get_canvas_group(), rv); + } + } + } delete rl; } @@ -656,7 +659,7 @@ bool Editor::canvas_selection_rect_event (GdkEvent *event, ArdourCanvas::Item* item, SelectionRect* rect) { bool ret = false; - + switch (event->type) { case GDK_BUTTON_PRESS: case GDK_2BUTTON_PRESS: @@ -682,7 +685,7 @@ Editor::canvas_selection_rect_event (GdkEvent *event, ArdourCanvas::Item* item, default: break; } - + return ret; } @@ -715,7 +718,7 @@ Editor::canvas_selection_start_trim_event (GdkEvent *event, ArdourCanvas::Item* default: break; } - + return ret; } @@ -748,7 +751,65 @@ Editor::canvas_selection_end_trim_event (GdkEvent *event, ArdourCanvas::Item* it default: break; } - + + return ret; +} + +bool +Editor::canvas_frame_handle_event (GdkEvent* event, ArdourCanvas::Item* item, RegionView* rv) +{ + bool ret = false; + + /* frame handles are not active when in internal edit mode, because actual notes + might be in the area occupied by the handle - we want them to be editable as normal. + */ + + if (internal_editing() || !rv->sensitive()) { + return false; + } + + /* NOTE: frame handles pretend to be the colored trim bar from an event handling + perspective. XXX change this ?? + */ + + ItemType type; + + if (item->get_data ("isleft")) { + type = LeftFrameHandle; + } else { + type = RightFrameHandle; + } + + switch (event->type) { + case GDK_BUTTON_PRESS: + case GDK_2BUTTON_PRESS: + case GDK_3BUTTON_PRESS: + clicked_regionview = rv; + clicked_control_point = 0; + clicked_axisview = &clicked_regionview->get_time_axis_view(); + clicked_routeview = dynamic_cast(clicked_axisview); + ret = button_press_handler (item, event, type); + break; + case GDK_BUTTON_RELEASE: + ret = button_release_handler (item, event, type); + break; + case GDK_MOTION_NOTIFY: + ret = motion_handler (item, event); + break; + case GDK_ENTER_NOTIFY: + set_entered_regionview (rv); + ret = enter_handler (item, event, type); + break; + + case GDK_LEAVE_NOTIFY: + set_entered_regionview (0); + ret = leave_handler (item, event, type); + break; + + default: + break; + } + return ret; } @@ -757,7 +818,7 @@ bool Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas::Item* item, RegionView* rv) { bool ret = false; - + if (!rv->sensitive()) { return false; } @@ -776,13 +837,16 @@ Editor::canvas_region_view_name_highlight_event (GdkEvent* event, ArdourCanvas:: ret = button_release_handler (item, event, RegionViewNameHighlight); break; case GDK_MOTION_NOTIFY: - ret = motion_handler (item, event); + motion_handler (item, event); + ret = true; // force this to avoid progagating the event into the regionview break; case GDK_ENTER_NOTIFY: + set_entered_regionview (rv); ret = enter_handler (item, event, RegionViewNameHighlight); break; case GDK_LEAVE_NOTIFY: + set_entered_regionview (0); ret = leave_handler (item, event, RegionViewNameHighlight); break; @@ -819,10 +883,12 @@ Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item ret = motion_handler (item, event); break; case GDK_ENTER_NOTIFY: + set_entered_regionview (rv); ret = enter_handler (item, event, RegionViewName); break; case GDK_LEAVE_NOTIFY: + set_entered_regionview (0); ret = leave_handler (item, event, RegionViewName); break; @@ -834,7 +900,46 @@ Editor::canvas_region_view_name_event (GdkEvent *event, ArdourCanvas::Item* item } bool -Editor::canvas_marker_event (GdkEvent *event, ArdourCanvas::Item* item, Marker* marker) +Editor::canvas_feature_line_event (GdkEvent *event, ArdourCanvas::Item* item, RegionView *rv) +{ + bool ret = false; + + switch (event->type) { + case GDK_BUTTON_PRESS: + case GDK_2BUTTON_PRESS: + case GDK_3BUTTON_PRESS: + clicked_regionview = 0; + clicked_control_point = 0; + clicked_axisview = 0; + clicked_routeview = 0; //dynamic_cast(clicked_axisview); + ret = button_press_handler (item, event, FeatureLineItem); + break; + + case GDK_BUTTON_RELEASE: + ret = button_release_handler (item, event, FeatureLineItem); + break; + + case GDK_MOTION_NOTIFY: + ret = motion_handler (item, event); + break; + + case GDK_ENTER_NOTIFY: + ret = enter_handler (item, event, FeatureLineItem); + break; + + case GDK_LEAVE_NOTIFY: + ret = leave_handler (item, event, FeatureLineItem); + break; + + default: + break; + } + + return ret; +} + +bool +Editor::canvas_marker_event (GdkEvent *event, ArdourCanvas::Item* item, Marker* /*marker*/) { return typed_event (item, event, MarkerItem); } @@ -864,13 +969,13 @@ Editor::canvas_cd_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item) } bool -Editor::canvas_tempo_marker_event (GdkEvent *event, ArdourCanvas::Item* item, TempoMarker* marker) +Editor::canvas_tempo_marker_event (GdkEvent *event, ArdourCanvas::Item* item, TempoMarker* /*marker*/) { return typed_event (item, event, TempoMarkerItem); } bool -Editor::canvas_meter_marker_event (GdkEvent *event, ArdourCanvas::Item* item, MeterMarker* marker) +Editor::canvas_meter_marker_event (GdkEvent *event, ArdourCanvas::Item* item, MeterMarker* /*marker*/) { return typed_event (item, event, MeterMarkerItem); } @@ -900,7 +1005,17 @@ Editor::canvas_zoom_rect_event (GdkEvent *event, ArdourCanvas::Item* item) } bool -Editor::track_canvas_drag_motion (Glib::RefPtr const & c, int x, int y, guint time) +Editor::canvas_note_event (GdkEvent *event, ArdourCanvas::Item* item) +{ + if (!internal_editing()) { + return false; + } + + return typed_event (item, event, NoteItem); +} + +bool +Editor::track_canvas_drag_motion (Glib::RefPtr const & /*c*/, int x, int y, guint /*time*/) { double wx; double wy; @@ -913,12 +1028,12 @@ Editor::track_canvas_drag_motion (Glib::RefPtr const & c, int /* assume we're dragging with button 1 */ event.motion.state = Gdk::BUTTON1_MASK; - if (_drag == 0) { + if (!_drags->active ()) { double px; double py; nframes64_t const pos = event_frame (&event, &px, &py); - + std::pair const tv = trackview_by_y_position (py); if (tv.first == 0) { return true; @@ -929,33 +1044,32 @@ Editor::track_canvas_drag_motion (Glib::RefPtr const & c, int return true; } - list > regions; - TreeView* source; - region_list_display.get_object_drag_data (regions, &source); - assert (regions.size() == 1); - boost::shared_ptr region = regions.front (); + boost::shared_ptr region = _regions->get_dragged_region (); + + if (!region) { + return true; + } boost::shared_ptr region_copy = RegionFactory::create (region); - if (boost::dynamic_pointer_cast (region_copy) != 0 && + if (boost::dynamic_pointer_cast (region_copy) != 0 && dynamic_cast (tv.first) == 0) { /* audio -> non-audio */ return true; } - if (boost::dynamic_pointer_cast (region_copy) == 0 && + if (boost::dynamic_pointer_cast (region_copy) == 0 && dynamic_cast (tv.first) != 0) { /* MIDI -> non-MIDI */ return true; } - - _drag = new RegionInsertDrag (this, region_copy, rtav, pos); - _drag->start_grab (&event); + + _drags->set (new RegionInsertDrag (this, region_copy, rtav, pos), &event); } - _drag->motion_handler (&event, false); + _drags->motion_handler (&event, false); return true; }