X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_mouse.cc;h=6e11b16862093de176f647e994e31740c93f80ad;hb=c4be8c2a676adb0810fdc5d2a9dc1577f654a274;hp=0a8ef4296bd58497fe90f27dc93d552de4699408;hpb=c04081681cbfd33b66947e63388bbcd737441887;p=ardour.git diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index 0a8ef4296b..6e11b16862 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -60,7 +60,6 @@ #include "automation_time_axis.h" #include "control_point.h" #include "prompter.h" -#include "utils.h" #include "selection.h" #include "keyboard.h" #include "editing.h" @@ -114,7 +113,7 @@ Editor::mouse_frame (framepos_t& where, bool& in_track_canvas) const return false; } - if (pointer_window != canvas_window && pointer_window != _time_bars_canvas->get_window()) { + if (pointer_window != canvas_window) { in_track_canvas = false; return false; } @@ -134,18 +133,16 @@ Editor::mouse_frame (framepos_t& where, bool& in_track_canvas) const framepos_t Editor::window_event_sample (GdkEvent const * event, double* pcx, double* pcy) const { - double x; - double y; + ArdourCanvas::Duple d; - if (!gdk_event_get_coords (event, &x, &y)) { + if (!gdk_event_get_coords (event, &d.x, &d.y)) { return 0; } /* event coordinates are in window units, so convert to canvas - * (i.e. account for scrolling) */ - ArdourCanvas::Duple d = _track_canvas->window_to_canvas (ArdourCanvas::Duple (x, y)); + d = _track_canvas->window_to_canvas (d); if (pcx) { *pcx = d.x; @@ -179,57 +176,12 @@ Editor::canvas_event_sample (GdkEvent const * event, double* pcx, double* pcy) c *pcy = y; } - /* note that pixel_to_sample() never returns less than zero, so even if the pixel + /* note that pixel_to_sample_from_event() never returns less than zero, so even if the pixel position is negative (as can be the case with motion events in particular), the frame location is always positive. */ - return pixel_to_sample (x); -} - -Gdk::Cursor* -Editor::which_grabber_cursor () -{ - Gdk::Cursor* c = _cursors->grabber; - - if (_internal_editing) { - switch (mouse_mode) { - case MouseDraw: - c = _cursors->midi_pencil; - break; - - case MouseObject: - c = _cursors->grabber_note; - break; - - case MouseTimeFX: - c = _cursors->midi_resize; - break; - - case MouseRange: - c = _cursors->grabber_note; - break; - - default: - break; - } - - } else { - - switch (_edit_point) { - case EditAtMouse: - c = _cursors->grabber_edit_point; - break; - default: - boost::shared_ptr m = _movable.lock(); - if (m && m->locked()) { - c = _cursors->speaker; - } - break; - } - } - - return c; + return pixel_to_sample_from_event (x); } void @@ -239,7 +191,6 @@ Editor::set_current_trimmable (boost::shared_ptr t) if (!st || st == t) { _trimmable = t; - set_canvas_cursor (); } } @@ -250,91 +201,7 @@ Editor::set_current_movable (boost::shared_ptr m) if (!sm || sm != m) { _movable = m; - set_canvas_cursor (); - } -} - -void -Editor::set_canvas_cursor () -{ - switch (mouse_mode) { - case MouseRange: - current_canvas_cursor = _cursors->selector; - if (_internal_editing) { - current_canvas_cursor = which_grabber_cursor(); - } - break; - - case MouseObject: - current_canvas_cursor = which_grabber_cursor(); - break; - - case MouseDraw: - current_canvas_cursor = _cursors->midi_pencil; - break; - - case MouseGain: - current_canvas_cursor = _cursors->cross_hair; - break; - - case MouseZoom: - if (Keyboard::the_keyboard().key_is_down (GDK_Control_L)) { - current_canvas_cursor = _cursors->zoom_out; - } else { - current_canvas_cursor = _cursors->zoom_in; - } - break; - - case MouseTimeFX: - current_canvas_cursor = _cursors->time_fx; // just use playhead - break; - - case MouseAudition: - current_canvas_cursor = _cursors->speaker; - break; - } - - if (!_internal_editing) { - switch (_join_object_range_state) { - case JOIN_OBJECT_RANGE_NONE: - break; - case JOIN_OBJECT_RANGE_OBJECT: - current_canvas_cursor = which_grabber_cursor (); - break; - case JOIN_OBJECT_RANGE_RANGE: - current_canvas_cursor = _cursors->selector; - break; - } } - - /* up-down cursor as a cue that automation can be dragged up and down when in join object/range mode */ - if (!_internal_editing && get_smart_mode() ) { - - double x, y; - get_pointer_position (x, y); - - if (x >= 0 && y >= 0) { - - vector items; - - _track_canvas->root()->add_items_at_point (ArdourCanvas::Duple (x,y), items); - - // first item will be the upper most - - if (!items.empty()) { - const ArdourCanvas::Item* i = items.front(); - - if (i && i->parent() && i->parent()->get_data (X_("timeselection"))) { - pair tvp = trackview_by_y_position (_last_motion_y); - if (dynamic_cast (tvp.first)) { - current_canvas_cursor = _cursors->up_down; - } - } - } - } - } - - set_canvas_cursor (current_canvas_cursor, true); } void @@ -365,6 +232,11 @@ Editor::set_mouse_mode (MouseMode m, bool force) return; } + if (ARDOUR::Profile->get_mixbus()) { + if ( m == MouseZoom) m = MouseObject; + if ( m == MouseCut) m = MouseObject; + } + Glib::RefPtr act; switch (m) { @@ -372,6 +244,10 @@ Editor::set_mouse_mode (MouseMode m, bool force) act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-range")); break; + case MouseCut: + act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-cut")); + break; + case MouseObject: act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-object")); break; @@ -415,6 +291,11 @@ Editor::mouse_mode_toggled (MouseMode m) Glib::RefPtr act; Glib::RefPtr tact; + if (ARDOUR::Profile->get_mixbus()) { + if ( m == MouseZoom) m = MouseObject; + if ( m == MouseCut) m = MouseObject; + } + switch (m) { case MouseRange: act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-range")); @@ -424,6 +305,10 @@ Editor::mouse_mode_toggled (MouseMode m) act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-object")); break; + case MouseCut: + act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-cut")); + break; + case MouseDraw: act = ActionManager::get_action (X_("MouseMode"), X_("set-mouse-mode-draw")); break; @@ -478,26 +363,14 @@ Editor::mouse_mode_toggled (MouseMode m) instant_save (); - //TODO: set button styles for smart buttons -/* - if ( smart_mode_action->get_active() ) { - if( mouse_mode == MouseObject ) { //smart active and object active - smart_mode_button.set_active(1); - smart_mode_button.set_name("smart mode button"); - mouse_move_button.set_name("smart mode button"); - } else { //smart active but object inactive - smart_mode_button.set_active(0); - smart_mode_button.set_name("smart mode button"); - mouse_move_button.set_name("mouse mode button"); - } - } else { - smart_mode_button.set_active(0); - smart_mode_button.set_name("mouse mode button"); - mouse_move_button.set_name("mouse mode button"); + /* this should generate a new enter event which will + trigger the appropiate cursor. + */ + + if (_track_canvas) { + _track_canvas->re_enter (); } -*/ - - set_canvas_cursor (); + set_gain_envelope_visibility (); update_time_selection_display (); @@ -543,11 +416,16 @@ Editor::step_mouse_mode (bool next) case MouseRange: if (next) set_mouse_mode (MouseDraw); - else set_mouse_mode (MouseObject); + else set_mouse_mode (MouseCut); + break; + + case MouseCut: + if (next) set_mouse_mode (MouseRange); + else set_mouse_mode (MouseDraw); break; case MouseDraw: - if (next) set_mouse_mode (MouseZoom); + if (next) set_mouse_mode (MouseCut); else set_mouse_mode (MouseRange); break; @@ -623,7 +501,12 @@ Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemTyp to cut notes or regions. */ - MouseMode eff_mouse_mode = mouse_mode; + MouseMode eff_mouse_mode = effective_mouse_mode (); + + if (eff_mouse_mode == MouseCut) { + /* never change selection in cut mode */ + return; + } if (get_smart_mode() && eff_mouse_mode == MouseRange && event->button.button == 3 && item_type == RegionItem) { /* context clicks are always about object properties, even if @@ -632,6 +515,20 @@ Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemTyp eff_mouse_mode = MouseObject; } + /* special case: allow drag of region fade in/out in object mode with join object/range enabled */ + if (get_smart_mode()) { + switch (item_type) { + case FadeInHandleItem: + case FadeInTrimHandleItem: + case FadeOutHandleItem: + case FadeOutTrimHandleItem: + eff_mouse_mode = MouseObject; + break; + default: + break; + } + } + if (((mouse_mode != MouseObject) && (mouse_mode != MouseAudition || item_type != RegionItem) && (mouse_mode != MouseTimeFX || item_type != RegionItem) && @@ -684,21 +581,15 @@ Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemTyp case RegionViewName: case LeftFrameHandle: case RightFrameHandle: - if (eff_mouse_mode != MouseRange) { - set_selected_regionview_from_click (press, op); - } else if (event->type == GDK_BUTTON_PRESS) { - set_selected_track_as_side_effect (op); - } - break; - case FadeInHandleItem: + case FadeInTrimHandleItem: case FadeInItem: case FadeOutHandleItem: + case FadeOutTrimHandleItem: case FadeOutItem: case StartCrossFadeItem: case EndCrossFadeItem: - if (eff_mouse_mode != MouseRange) { - cerr << "Should be setting selected regionview\n"; + if (get_smart_mode() || eff_mouse_mode != MouseRange) { set_selected_regionview_from_click (press, op); } else if (event->type == GDK_BUTTON_PRESS) { set_selected_track_as_side_effect (op); @@ -789,6 +680,10 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT case MarkerBarItem: case TempoBarItem: case MeterBarItem: + case TimecodeRulerItem: + case SamplesRulerItem: + case MinsecRulerItem: + case BBTRulerItem: if (!Keyboard::modifier_state_equals (event->button.state, Keyboard::PrimaryModifier)) { _drags->set (new CursorDrag (this, *playhead_cursor, false), event); } @@ -844,8 +739,17 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT Editing::MouseMode eff = effective_mouse_mode (); /* special case: allow drag of region fade in/out in object mode with join object/range enabled */ - if (item_type == FadeInHandleItem || item_type == FadeOutHandleItem) { - eff = MouseObject; + if (get_smart_mode()) { + switch (item_type) { + case FadeInHandleItem: + case FadeInTrimHandleItem: + case FadeOutHandleItem: + case FadeOutTrimHandleItem: + eff = MouseObject; + break; + default: + break; + } } /* there is no Range mode when in internal edit mode */ @@ -872,19 +776,9 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT /* grab selection for moving */ _drags->set (new SelectionDrag (this, item, SelectionDrag::SelectionMove), event); } else { - double const y = event->button.y; - pair tvp = trackview_by_y_position (y); - if (tvp.first) { - AutomationTimeAxisView* atv = dynamic_cast (tvp.first); - if ( get_smart_mode() && atv) { - /* smart "join" mode: drag automation */ - _drags->set (new AutomationRangeDrag (this, atv, selection->time), event, _cursors->up_down); - } else { - /* this was debated, but decided the more common action was to - make a new selection */ - _drags->set (new SelectionDrag (this, item, SelectionDrag::CreateSelection), event); - } - } + /* this was debated, but decided the more common action was to + make a new selection */ + _drags->set (new SelectionDrag (this, item, SelectionDrag::CreateSelection), event); } break; @@ -953,6 +847,26 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT } break; + case MouseCut: + switch (item_type) { + case RegionItem: + case FadeInHandleItem: + case FadeOutHandleItem: + case LeftFrameHandle: + case RightFrameHandle: + case FeatureLineItem: + case RegionViewNameHighlight: + case RegionViewName: + case StreamItem: + case AutomationTrackItem: + _drags->set (new RegionCutDrag (this, item, canvas_event_sample (event)), event, current_canvas_cursor); + return true; + break; + default: + break; + } + break; + case MouseObject: switch (item_type) { case NoteItem: @@ -1046,18 +960,28 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT case RegionViewNameHighlight: case LeftFrameHandle: - case RightFrameHandle: + case RightFrameHandle: if (!clicked_regionview->region()->locked()) { _drags->set (new TrimDrag (this, item, clicked_regionview, selection->regions.by_layer()), event); return true; } break; + case FadeInTrimHandleItem: + case FadeOutTrimHandleItem: + if (!clicked_regionview->region()->locked()) { + _drags->set (new TrimDrag (this, item, clicked_regionview, selection->regions.by_layer(), true), event); + return true; + } + break; + case RegionViewName: { /* rename happens on edit clicks */ - _drags->set (new TrimDrag (this, clicked_regionview->get_name_highlight(), clicked_regionview, selection->regions.by_layer()), event); - return true; + if (clicked_regionview->get_name_highlight()) { + _drags->set (new TrimDrag (this, clicked_regionview->get_name_highlight(), clicked_regionview, selection->regions.by_layer()), event); + return true; + } break; } @@ -1114,45 +1038,6 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT case SelectionItem: { - if ( get_smart_mode() ) { - /* we're in "smart" joined mode, and we've clicked on a Selection */ - double const y = event->button.y; - pair tvp = trackview_by_y_position (y); - if (tvp.first) { - /* if we're over an automation track, start a drag of its data */ - AutomationTimeAxisView* atv = dynamic_cast (tvp.first); - if (atv) { - _drags->set (new AutomationRangeDrag (this, atv, selection->time), event, _cursors->up_down); - } - - /* if we're over a track and a region, and in the `object' part of a region, - put a selection around the region and drag both - */ -/* RouteTimeAxisView* rtv = dynamic_cast (tvp.first); - if (rtv && _join_object_range_state == JOIN_OBJECT_RANGE_OBJECT) { - boost::shared_ptr t = boost::dynamic_pointer_cast (rtv->route ()); - if (t) { - boost::shared_ptr pl = t->playlist (); - if (pl) { - - boost::shared_ptr r = pl->top_region_at (canvas_event_sample (event)); - if (r) { - RegionView* rv = rtv->view()->find_view (r); - clicked_selection = select_range (rv->region()->position(), - rv->region()->last_frame()+1); - _drags->add (new SelectionDrag (this, item, SelectionDrag::SelectionMove)); - list rvs; - rvs.push_back (rv); - _drags->add (new RegionMoveDrag (this, item, rv, rvs, false, false)); - _drags->start_grab (event); - return true; - } - } - } - } -*/ - } - } break; } @@ -1183,7 +1068,16 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT AudioRegionView* arv = dynamic_cast (clicked_regionview); if (arv) { _drags->set (new AutomationRangeDrag (this, arv, selection->time), event, _cursors->up_down); - _drags->start_grab (event); + } else { + double const y = event->button.y; + pair tvp = trackview_by_y_position (y); + if (tvp.first) { + AutomationTimeAxisView* atv = dynamic_cast (tvp.first); + if ( atv) { + /* smart "join" mode: drag automation */ + _drags->set (new AutomationRangeDrag (this, atv, selection->time), event, _cursors->up_down); + } + } } return true; break; @@ -1229,7 +1123,7 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT scrub_reverse_distance = 0; last_scrub_x = event->button.x; scrubbing_direction = 0; - set_canvas_cursor (_cursors->transparent); + push_canvas_cursor (_cursors->transparent); return true; break; @@ -1272,12 +1166,12 @@ Editor::button_press_handler_2 (ArdourCanvas::Item* item, GdkEvent* event, ItemT switch (item_type) { case RegionViewNameHighlight: - _drags->set (new TrimDrag (this, item, clicked_regionview, selection->regions.by_layer()), event); - return true; - break; + _drags->set (new TrimDrag (this, item, clicked_regionview, selection->regions.by_layer()), event); + return true; + break; - case LeftFrameHandle: - case RightFrameHandle: + case LeftFrameHandle: + case RightFrameHandle: if (!internal_editing ()) { _drags->set (new TrimDrag (this, item, clicked_regionview, selection->regions.by_layer()), event); } @@ -1333,21 +1227,6 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp return false; } - Glib::RefPtr canvas_window = const_cast(this)->_track_canvas_viewport->get_window(); - - if (canvas_window) { - Glib::RefPtr pointer_window; - int x, y; - double wx, wy; - Gdk::ModifierType mask; - - pointer_window = canvas_window->get_pointer (x, y, mask); - - if (pointer_window == _track_canvas->get_window()) { - _track_canvas->window_to_canvas (x, y, wx, wy); - } - } - pre_press_cursor = current_canvas_cursor; _track_canvas->grab_focus(); @@ -1380,7 +1259,11 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp case CdMarkerBarItem: case TransportMarkerBarItem: case StreamItem: - /* button press on these events never does anything to + case TimecodeRulerItem: + case SamplesRulerItem: + case MinsecRulerItem: + case BBTRulerItem: + /* button press on these items never does anything to change the editing mode. */ break; @@ -1406,7 +1289,7 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp } //not rolling, range mode click + join_play_range : locate the PH here - if ( !_drags->active () && !_session->transport_rolling() && ( effective_mouse_mode() == MouseRange ) && Config->get_always_play_range() ) { + if ( !_drags->active () && !_session->transport_rolling() && ( effective_mouse_mode() == MouseRange ) && Config->get_follow_edits() ) { framepos_t where = canvas_event_sample (event); snap_to(where); _session->request_locate (where, false); @@ -1558,16 +1441,17 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT switch (item_type) { case FadeInItem: case FadeInHandleItem: - case FadeOutItem: - case FadeOutHandleItem: - popup_fade_context_menu (1, event->button.time, item, item_type); - break; - + case FadeInTrimHandleItem: case StartCrossFadeItem: + case LeftFrameHandle: popup_xfade_in_context_menu (1, event->button.time, item, item_type); break; + case FadeOutItem: + case FadeOutHandleItem: + case FadeOutTrimHandleItem: case EndCrossFadeItem: + case RightFrameHandle: popup_xfade_out_context_menu (1, event->button.time, item, item_type); break; @@ -1577,8 +1461,6 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT case RegionItem: case RegionViewNameHighlight: - case LeftFrameHandle: - case RightFrameHandle: case RegionViewName: popup_track_context_menu (1, event->button.time, item_type, false); break; @@ -1598,6 +1480,10 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT case TempoBarItem: case MeterBarItem: case VideoBarItem: + case TimecodeRulerItem: + case SamplesRulerItem: + case MinsecRulerItem: + case BBTRulerItem: popup_ruler_menu (where, item_type); break; @@ -1710,6 +1596,13 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT return true; break; + case TimecodeRulerItem: + case SamplesRulerItem: + case MinsecRulerItem: + case BBTRulerItem: + return true; + break; + default: break; } @@ -1760,7 +1653,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT break; case MouseAudition: - set_canvas_cursor (current_canvas_cursor); + pop_canvas_cursor (); if (scrubbing_direction == 0) { /* no drag, just a click */ switch (item_type) { @@ -1841,26 +1734,24 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ double fraction; bool ret = true; + /* by the time we reach here, entered_regionview and entered trackview + * will have already been set as appropriate. Things are done this + * way because this method isn't passed a pointer to a variable type of + * thing that is entered (which may or may not be canvas item). + * (e.g. the actual entered regionview) + */ + + choose_canvas_cursor_on_entry (&event->crossing, item_type); + switch (item_type) { case ControlPointItem: if (mouse_mode == MouseGain || mouse_mode == MouseObject) { cp = static_cast(item->get_data ("control_point")); cp->show (); - double at_x, at_y; - at_x = cp->get_x(); - at_y = cp->get_y (); - cp->i2w (at_x, at_y); - at_x += 10.0; - at_y += 10.0; - fraction = 1.0 - (cp->get_y() / cp->line().height()); - if (is_drawable() && !_drags->active ()) { - set_canvas_cursor (_cursors->fader); - } - - _verbose_cursor->set (cp->line().get_verbose_cursor_string (fraction), at_x, at_y); + _verbose_cursor->set (cp->line().get_verbose_cursor_string (fraction)); _verbose_cursor->show (); } break; @@ -1871,9 +1762,6 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ if (line) { line->set_outline_color (ARDOUR_UI::config()->get_canvasvar_EnteredGainLine()); } - if (is_drawable()) { - set_canvas_cursor (_cursors->fader); - } } break; @@ -1883,108 +1771,14 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ if (line) { line->set_outline_color (ARDOUR_UI::config()->get_canvasvar_EnteredAutomationLine()); } - if (is_drawable()) { - set_canvas_cursor (_cursors->fader); - } - } - break; - - case RegionViewNameHighlight: - if (is_drawable() && effective_mouse_mode() == MouseObject && entered_regionview) { - set_canvas_cursor_for_region_view (event->crossing.x, entered_regionview); - _over_region_trim_target = true; } break; - case LeftFrameHandle: - case RightFrameHandle: - if (is_drawable() && effective_mouse_mode() == MouseObject && !internal_editing() && entered_regionview) { - set_canvas_cursor_for_region_view (event->crossing.x, entered_regionview); - } - break; - - case RegionItem: - switch (effective_mouse_mode()) { - case MouseRange: - set_canvas_cursor (_cursors->selector); - break; - default: - set_canvas_cursor (which_grabber_cursor()); - break; - } - break; - - case StartSelectionTrimItem: - if (is_drawable()) { - set_canvas_cursor (_cursors->left_side_trim); - } - break; - case EndSelectionTrimItem: - if (is_drawable()) { - set_canvas_cursor (_cursors->right_side_trim); - } - break; - - case PlayheadCursorItem: - if (is_drawable()) { - switch (_edit_point) { - case EditAtMouse: - set_canvas_cursor (_cursors->grabber_edit_point); - break; - default: - set_canvas_cursor (_cursors->grabber); - break; - } - } - break; - - - case RegionViewName: - - /* when the name is not an active item, the entire name highlight is for trimming */ - - if (!reinterpret_cast (item->get_data ("regionview"))->name_active()) { - if (mouse_mode == MouseObject && is_drawable()) { - set_canvas_cursor_for_region_view (event->crossing.x, entered_regionview); - _over_region_trim_target = true; - } - } - break; - - case AutomationTrackItem: - if (is_drawable()) { - Gdk::Cursor *cursor; - switch (mouse_mode) { - case MouseRange: - cursor = _cursors->selector; - break; - case MouseZoom: - cursor = _cursors->zoom_in; - break; - default: - cursor = _cursors->cross_hair; - break; - } - - set_canvas_cursor (cursor); - - AutomationTimeAxisView* atv; - if ((atv = static_cast(item->get_data ("trackview"))) != 0) { - clear_entered_track = false; - set_entered_track (atv); - } - } - break; - - case MarkerBarItem: - case RangeMarkerBarItem: - case TransportMarkerBarItem: - case CdMarkerBarItem: - case MeterBarItem: - case TempoBarItem: - if (is_drawable()) { - set_canvas_cursor (_cursors->timebar); + AutomationTimeAxisView* atv; + if ((atv = static_cast(item->get_data ("trackview"))) != 0) { + clear_entered_track = false; + set_entered_track (atv); } break; @@ -1997,32 +1791,30 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ // fall through case MeterMarkerItem: case TempoMarkerItem: - if (is_drawable()) { - set_canvas_cursor (_cursors->timebar); - } break; case FadeInHandleItem: + case FadeInTrimHandleItem: if (mouse_mode == MouseObject && !internal_editing()) { ArdourCanvas::Rectangle *rect = dynamic_cast (item); if (rect) { RegionView* rv = static_cast(item->get_data ("regionview")); rect->set_fill_color (rv->get_fill_color()); - set_canvas_cursor (_cursors->fade_in); } } break; case FadeOutHandleItem: + case FadeOutTrimHandleItem: if (mouse_mode == MouseObject && !internal_editing()) { ArdourCanvas::Rectangle *rect = dynamic_cast (item); if (rect) { RegionView* rv = static_cast(item->get_data ("regionview")); rect->set_fill_color (rv->get_fill_color ()); - set_canvas_cursor (_cursors->fade_out); } } break; + case FeatureLineItem: { ArdourCanvas::Line *line = dynamic_cast (item); @@ -2031,16 +1823,13 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ break; case SelectionItem: - if ( get_smart_mode() ) { - set_canvas_cursor (); - } break; default: break; } - /* second pass to handle entered track status in a comprehensible way. + /* third pass to handle entered track status in a comprehensible way. */ switch (item_type) { @@ -2056,7 +1845,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ break; default: - set_entered_track (0); + break; } @@ -2069,31 +1858,12 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent*, ItemType item_type) AutomationLine* al; Marker *marker; Location *loc; - RegionView* rv; bool is_start; bool ret = true; switch (item_type) { case ControlPointItem: - if (is_drawable()) { - set_canvas_cursor (current_canvas_cursor); - } - - _verbose_cursor->hide (); - break; - - case RegionViewNameHighlight: - case LeftFrameHandle: - case RightFrameHandle: - case StartSelectionTrimItem: - case EndSelectionTrimItem: - case PlayheadCursorItem: - - _over_region_trim_target = false; - - if (is_drawable()) { - set_canvas_cursor (current_canvas_cursor); - } + _verbose_cursor->hide (); break; case GainLineItem: @@ -2105,31 +1875,6 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent*, ItemType item_type) line->set_outline_color (al->get_line_color()); } } - if (is_drawable()) { - set_canvas_cursor (current_canvas_cursor); - } - break; - - case RegionViewName: - /* see enter_handler() for notes */ - _over_region_trim_target = false; - - if (!reinterpret_cast (item->get_data ("regionview"))->name_active()) { - if (is_drawable() && mouse_mode == MouseObject) { - set_canvas_cursor (current_canvas_cursor); - } - } - break; - - case RangeMarkerBarItem: - case TransportMarkerBarItem: - case CdMarkerBarItem: - case MeterBarItem: - case TempoBarItem: - case MarkerBarItem: - if (is_drawable()) { - set_canvas_cursor (current_canvas_cursor); - } break; case MarkerItem: @@ -2143,38 +1888,29 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent*, ItemType item_type) // fall through case MeterMarkerItem: case TempoMarkerItem: - - if (is_drawable()) { - set_canvas_cursor (current_canvas_cursor); - } - break; + case FadeInTrimHandleItem: + case FadeOutTrimHandleItem: case FadeInHandleItem: case FadeOutHandleItem: - rv = static_cast(item->get_data ("regionview")); - { - ArdourCanvas::Rectangle *rect = dynamic_cast (item); - if (rect) { - rect->set_fill_color (ARDOUR_UI::config()->get_canvasvar_InactiveFadeHandle()); - } + { + ArdourCanvas::Rectangle *rect = dynamic_cast (item); + if (rect) { + rect->set_fill_color (ARDOUR_UI::config()->get_canvasvar_InactiveFadeHandle()); } - set_canvas_cursor (current_canvas_cursor); - break; + } + break; case AutomationTrackItem: - if (is_drawable()) { - set_canvas_cursor (current_canvas_cursor); - clear_entered_track = true; - Glib::signal_idle().connect (sigc::mem_fun(*this, &Editor::left_automation_track)); - } break; + case FeatureLineItem: - { - ArdourCanvas::Line *line = dynamic_cast (item); - line->set_outline_color (ARDOUR_UI::config()->get_canvasvar_ZeroLine()); - } - break; + { + ArdourCanvas::Line *line = dynamic_cast (item); + line->set_outline_color (ARDOUR_UI::config()->get_canvasvar_ZeroLine()); + } + break; default: break; @@ -2183,16 +1919,6 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent*, ItemType item_type) return ret; } -gint -Editor::left_automation_track () -{ - if (clear_entered_track) { - set_entered_track (0); - clear_entered_track = false; - } - return false; -} - void Editor::scrub (framepos_t frame, double current_x) { @@ -2297,34 +2023,19 @@ Editor::motion_handler (ArdourCanvas::Item* /*item*/, GdkEvent* event, bool from current_stepping_trackview = 0; step_timeout.disconnect (); } - + if (_session && _session->actively_recording()) { /* Sorry. no dragging stuff around while we record */ return true; } - - JoinObjectRangeState const old = _join_object_range_state; - update_join_object_range_location (event->motion.x, event->motion.y); - - if (!_internal_editing && _join_object_range_state != old) { - set_canvas_cursor (); - } - - if (!_internal_editing && _over_region_trim_target) { - set_canvas_cursor_for_region_view (event->motion.x, entered_regionview); - } - - bool handled = false; + + update_join_object_range_location (event->motion.y); + if (_drags->active ()) { - handled = _drags->motion_handler (event, from_autoscroll); + return _drags->motion_handler (event, from_autoscroll); } - if (!handled) { - return false; - } - - track_canvas_motion (event); - return true; + return false; } bool @@ -2399,19 +2110,19 @@ Editor::edit_notes (TimeAxisViewItem& tavi) if (s.empty ()) { return; } - + EditNoteDialog* d = new EditNoteDialog (&(*s.begin())->region_view(), s); - d->show_all (); + d->show_all (); ensure_float (*d); - d->signal_response().connect (sigc::bind (sigc::mem_fun (*this, &Editor::note_edit_done), d)); + d->signal_response().connect (sigc::bind (sigc::mem_fun (*this, &Editor::note_edit_done), d)); } void Editor::note_edit_done (int r, EditNoteDialog* d) { - d->done (r); - delete d; + d->done (r); + delete d; } void @@ -2481,7 +2192,7 @@ Editor::collect_new_region_view (RegionView* rv) void Editor::collect_and_select_new_region_view (RegionView* rv) { - selection->add(rv); + selection->add(rv); latest_regionviews.push_back (rv); } @@ -2499,7 +2210,7 @@ Editor::cancel_selection () void Editor::cancel_time_selection () { - for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { + for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { (*i)->hide_selection (); } selection->time.clear (); @@ -2685,12 +2396,17 @@ Editor::add_region_drag (ArdourCanvas::Item* item, GdkEvent*, RegionView* region return; } - _region_motion_group->raise_to_top (); + switch (Config->get_edit_mode()) { + case Splice: + _drags->add (new RegionSpliceDrag (this, item, region_view, selection->regions.by_layer())); + break; + case Ripple: + _drags->add (new RegionRippleDrag (this, item, region_view, selection->regions.by_layer())); + break; + default: + _drags->add (new RegionMoveDrag (this, item, region_view, selection->regions.by_layer(), false, false)); + break; - if (Config->get_edit_mode() == Splice) { - _drags->add (new RegionSpliceDrag (this, item, region_view, selection->regions.by_layer())); - } else { - _drags->add (new RegionMoveDrag (this, item, region_view, selection->regions.by_layer(), false, false)); } } @@ -2703,8 +2419,6 @@ Editor::add_region_copy_drag (ArdourCanvas::Item* item, GdkEvent*, RegionView* r return; } - _region_motion_group->raise_to_top (); - _drags->add (new RegionMoveDrag (this, item, region_view, selection->regions.by_layer(), false, true)); } @@ -2717,7 +2431,7 @@ Editor::add_region_brush_drag (ArdourCanvas::Item* item, GdkEvent*, RegionView* return; } - if (Config->get_edit_mode() == Splice) { + if (Config->get_edit_mode() == Splice || Config->get_edit_mode() == Ripple) { return; } @@ -2807,15 +2521,15 @@ Editor::set_internal_edit (bool yn) } _internal_editing = yn; - + if (yn) { - pre_internal_mouse_mode = mouse_mode; + pre_internal_mouse_mode = mouse_mode; pre_internal_snap_type = _snap_type; pre_internal_snap_mode = _snap_mode; - for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { - (*i)->enter_internal_edit_mode (); - } + for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { + (*i)->enter_internal_edit_mode (); + } set_snap_to (internal_snap_type); set_snap_mode (internal_snap_mode); @@ -2825,62 +2539,84 @@ Editor::set_internal_edit (bool yn) internal_snap_mode = _snap_mode; internal_snap_type = _snap_type; - for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { - (*i)->leave_internal_edit_mode (); - } + for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { + (*i)->leave_internal_edit_mode (); + } - if (mouse_mode == MouseDraw && pre_internal_mouse_mode != MouseDraw) { - /* we were drawing .. flip back to something sensible */ - set_mouse_mode (pre_internal_mouse_mode); - } + if (mouse_mode == MouseDraw && pre_internal_mouse_mode != MouseDraw) { + /* we were drawing .. flip back to something sensible */ + set_mouse_mode (pre_internal_mouse_mode); + } set_snap_to (pre_internal_snap_type); set_snap_mode (pre_internal_snap_mode); } - - set_canvas_cursor (); + + reset_canvas_cursor (); } -/** Update _join_object_range_state which indicate whether we are over the top or bottom half of a region view, - * used by the `join object/range' tool mode. +/** Update _join_object_range_state which indicate whether we are over the top + * or bottom half of a route view, used by the `join object/range' tool + * mode. Coordinates in canvas space. */ void -Editor::update_join_object_range_location (double /*x*/, double y) +Editor::update_join_object_range_location (double y) { - /* XXX: actually, this decides based on whether the mouse is in the top - or bottom half of a the waveform part RouteTimeAxisView; - - Note that entered_{track,regionview} is not always setup (e.g. if - the mouse is over a TimeSelection), and to get a Region - that we're over requires searching the playlist. - */ - - if ( !get_smart_mode() ) { + if (_internal_editing || !get_smart_mode()) { _join_object_range_state = JOIN_OBJECT_RANGE_NONE; return; } + JoinObjectRangeState const old = _join_object_range_state; + if (mouse_mode == MouseObject) { _join_object_range_state = JOIN_OBJECT_RANGE_OBJECT; } else if (mouse_mode == MouseRange) { _join_object_range_state = JOIN_OBJECT_RANGE_RANGE; } - /* XXX: maybe we should make entered_track work in all cases, rather than resorting to this */ - pair tvp = trackview_by_y_position (y); + if (entered_regionview) { - if (tvp.first) { + ArdourCanvas::Duple const item_space = entered_regionview->get_canvas_group()->canvas_to_item (ArdourCanvas::Duple (0, y)); + double const c = item_space.y / entered_regionview->height(); + + _join_object_range_state = c <= 0.5 ? JOIN_OBJECT_RANGE_RANGE : JOIN_OBJECT_RANGE_OBJECT; + + if (_join_object_range_state != old) { + set_canvas_cursor (which_track_cursor ()); + } - RouteTimeAxisView* rtv = dynamic_cast (tvp.first); - if (rtv) { + } else if (entered_track) { + + RouteTimeAxisView* entered_route_view = dynamic_cast (entered_track); + + if (entered_route_view) { double cx = 0; double cy = y; - rtv->canvas_display()->canvas_to_item (cx, cy); - double const c = cy / (rtv->view()->child_height() - TimeAxisViewItem::NAME_HIGHLIGHT_SIZE); + entered_route_view->canvas_display()->canvas_to_item (cx, cy); + + double track_height = entered_route_view->view()->child_height(); + if (Config->get_show_name_highlight()) { + track_height -= TimeAxisViewItem::NAME_HIGHLIGHT_SIZE; + } + double const c = cy / track_height; + + + if (c <= 0.5) { + _join_object_range_state = JOIN_OBJECT_RANGE_RANGE; + } else { + _join_object_range_state = JOIN_OBJECT_RANGE_OBJECT; + } + + } else { + /* Other kinds of tracks use object mode */ + _join_object_range_state = JOIN_OBJECT_RANGE_OBJECT; + } - _join_object_range_state = c <= 0.5 ? JOIN_OBJECT_RANGE_RANGE : JOIN_OBJECT_RANGE_OBJECT; + if (_join_object_range_state != old) { + set_canvas_cursor (which_track_cursor ()); } } } @@ -2906,46 +2642,6 @@ Editor::remove_midi_note (ArdourCanvas::Item* item, GdkEvent *) e->region_view().delete_note (e->note ()); } -void -Editor::set_canvas_cursor_for_region_view (double x, RegionView* rv) -{ - /* XXX: this check should not be necessary */ - if (rv == 0) { - return; - } - - assert (rv); - - ArdourCanvas::Group* g = rv->get_canvas_group (); - ArdourCanvas::Group* p = g->parent (); - - /* Compute x in region view parent coordinates */ - double dy = 0; - p->canvas_to_item (x, dy); - - boost::optional item_bbox = g->bounding_box (); - assert (item_bbox); - ArdourCanvas::Rect parent_bbox = g->item_to_parent (item_bbox.get ()); - - /* Halfway across the region */ - double const h = (parent_bbox.x0 + parent_bbox.x1) / 2; - - Trimmable::CanTrim ct = rv->region()->can_trim (); - if (x <= h) { - if (ct & Trimmable::FrontTrimEarlier) { - set_canvas_cursor (_cursors->left_side_trim, true); - } else { - set_canvas_cursor (_cursors->left_side_trim_right_only, true); - } - } else { - if (ct & Trimmable::EndTrimLater) { - set_canvas_cursor (_cursors->right_side_trim, true); - } else { - set_canvas_cursor (_cursors->right_side_trim_left_only, true); - } - } -} - /** Obtain the pointer position in canvas coordinates */ void Editor::get_pointer_position (double& x, double& y) const