X-Git-Url: https://main.carlh.net/gitweb/?a=blobdiff_plain;f=gtk2_ardour%2Feditor_mouse.cc;h=6a3eaa9084cc65b436dc963ce1c31a8887fd5a2a;hb=33e58df92c0b6731bdabe96f67bebad665c5d8da;hp=f1640538f6f64732f9eca3aba25ad83de0960dfb;hpb=97721226a489c6f78c27997183cee1b5a3d479ff;p=ardour.git diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index f1640538f6..6a3eaa9084 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -53,6 +53,7 @@ #include "rgb_macros.h" #include "control_point_dialog.h" #include "editor_drag.h" +#include "automation_region_view.h" #include "ardour/types.h" #include "ardour/profile.h" @@ -177,7 +178,7 @@ Editor::which_grabber_cursor () break; case MouseObject: - c = grabber_cursor; + c = grabber_note_cursor; break; case MouseTimeFX: @@ -325,6 +326,8 @@ Editor::mouse_mode_toggled (MouseMode m) instant_save (); + cerr << "Mouse mode toggled to " << m << endl; + if (!internal_editing()) { if (mouse_mode != MouseRange && _join_object_range_state == JOIN_OBJECT_RANGE_NONE) { @@ -425,6 +428,10 @@ Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemTyp region alignment. note: not dbl-click or triple-click + + Also note that there is no region selection in internal edit mode, otherwise + for operations operating on the selection (e.g. cut) it is not obvious whether + to cut notes or regions. */ if (((mouse_mode != MouseObject) && @@ -433,8 +440,8 @@ Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemTyp (mouse_mode != MouseTimeFX || item_type != RegionItem) && (mouse_mode != MouseGain) && (mouse_mode != MouseRange)) || - - ((event->type != GDK_BUTTON_PRESS && event->type != GDK_BUTTON_RELEASE) || event->button.button > 3)) { + ((event->type != GDK_BUTTON_PRESS && event->type != GDK_BUTTON_RELEASE) || event->button.button > 3) || + internal_editing()) { return; } @@ -467,11 +474,12 @@ Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemTyp if (_join_object_range_state == JOIN_OBJECT_RANGE_OBJECT && !selection->regions.empty()) { clicked_selection = select_range_around_region (selection->regions.front()); } - break; case RegionViewNameHighlight: case RegionViewName: + case LeftFrameHandle: + case RightFrameHandle: if (mouse_mode != MouseRange || _join_object_range_state == JOIN_OBJECT_RANGE_OBJECT) { set_selected_regionview_from_click (press, op, true); } else if (event->type == GDK_BUTTON_PRESS) { @@ -492,7 +500,7 @@ Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemTyp break; case ControlPointItem: - set_selected_track_as_side_effect (); + set_selected_track_as_side_effect (true); if (mouse_mode != MouseRange || _join_object_range_state == JOIN_OBJECT_RANGE_OBJECT) { set_selected_control_point_from_click (op, false); } @@ -518,10 +526,6 @@ Editor::button_selection (ArdourCanvas::Item* /*item*/, GdkEvent* event, ItemTyp bool Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_type) { - if (_drags->active ()) { - _drags->abort (); - } - /* single mouse clicks on any of these item types operate independent of mouse mode, mostly because they are not on the main track canvas or because we want @@ -661,6 +665,33 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT } break; + case NoteItem: + if (internal_editing()) { + /* trim notes if we're in internal edit mode and near the ends of the note */ + _drags->set (new NoteResizeDrag (this, item), event); + } + return true; + + case StreamItem: + if (internal_editing()) { + _drags->set (new RegionCreateDrag (this, item, clicked_axisview), event); + return true; + } else { + _drags->set (new SelectionDrag (this, item, SelectionDrag::CreateSelection), event); + return true; + } + break; + + case RegionViewNameHighlight: + case LeftFrameHandle: + case RightFrameHandle: + { + RegionSelection s = get_equivalent_regions (selection->regions, Properties::edit.property_id); + _drags->set (new TrimDrag (this, item, clicked_regionview, s.by_layer()), event); + return true; + break; + } + default: if (!internal_editing()) { _drags->set (new SelectionDrag (this, item, SelectionDrag::CreateSelection), event); @@ -704,15 +735,36 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT return true; } + case FeatureLineItem: + { + if (Keyboard::modifier_state_contains (event->button.state, Keyboard::TertiaryModifier)) { + remove_transient(item); + return true; + } + + _drags->set (new FeatureLineDrag (this, item), event); + return true; + break; + } + case RegionItem: + if (dynamic_cast (clicked_regionview)) { + /* click on an automation region view; do nothing here and let the ARV's signal handler + sort it out. + */ + break; + } + + /* click on a normal region view */ if (Keyboard::modifier_state_contains (event->button.state, Keyboard::CopyModifier)) { add_region_copy_drag (item, event, clicked_regionview); - } else if (Keyboard::the_keyboard().key_is_down (GDK_b)) { + } + else if (Keyboard::the_keyboard().key_is_down (GDK_b)) { add_region_brush_drag (item, event, clicked_regionview); } else { add_region_drag (item, event, clicked_regionview); } - + if (_join_object_range_state == JOIN_OBJECT_RANGE_OBJECT && !selection->regions.empty()) { _drags->add (new SelectionDrag (this, clicked_axisview->get_selection_rect (clicked_selection)->rect, SelectionDrag::SelectionMove)); } @@ -721,12 +773,14 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT break; case RegionViewNameHighlight: - { - RegionSelection s = get_equivalent_regions (selection->regions, Properties::edit.property_id); - _drags->set (new TrimDrag (this, item, clicked_regionview, s.by_layer()), event); - return true; + case LeftFrameHandle: + case RightFrameHandle: + if (!internal_editing ()) { + RegionSelection s = get_equivalent_regions (selection->regions, Properties::edit.property_id); + _drags->set (new TrimDrag (this, item, clicked_regionview, s.by_layer()), event); + return true; + } break; - } case RegionViewName: { @@ -947,7 +1001,11 @@ 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); + case LeftFrameHandle: + case RightFrameHandle: + if (!internal_editing ()) { + _drags->set (new TrimDrag (this, item, clicked_regionview, selection->regions.by_layer()), event); + } return true; break; @@ -1003,9 +1061,6 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp if (pointer_window == track_canvas->get_bin_window()) { track_canvas->window_to_world (x, y, wx, wy); - allow_vertical_scroll = true; - } else { - allow_vertical_scroll = false; } } @@ -1058,7 +1113,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT return true; } - /* first, see if we're finishing a drag ... */ + /* see if we're finishing a drag */ bool were_dragging = false; if (_drags->active ()) { @@ -1071,8 +1126,6 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT were_dragging = true; } - button_selection (item, event, item_type); - /* edit events get handled here */ if (!_drags->active () && Keyboard::is_edit_event (&event->button)) { @@ -1129,6 +1182,8 @@ 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, where); break; @@ -1222,6 +1277,10 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT } break; + case NoteItem: + remove_midi_note (item, event); + break; + default: break; } @@ -1291,23 +1350,20 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT break; case MouseGain: - // Gain only makes sense for audio regions - - if (!dynamic_cast(clicked_regionview)) { - break; - } - switch (item_type) { case RegionItem: + { /* check that we didn't drag before releasing, since its really annoying to create new control points when doing this. */ - if (were_dragging) { - dynamic_cast(clicked_regionview)->add_gain_point_event (item, event); + AudioRegionView* arv = dynamic_cast (clicked_regionview); + if (were_dragging && arv) { + arv->add_gain_point_event (item, event); } return true; break; + } case AutomationTrackItem: dynamic_cast(clicked_axisview)-> @@ -1394,6 +1450,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ ControlPoint* cp; Marker * marker; double fraction; + bool ret = true; if (last_item_entered != item) { last_item_entered = item; @@ -1452,11 +1509,23 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ break; case RegionViewNameHighlight: - if (is_drawable() && mouse_mode == MouseObject) { + if (is_drawable() && mouse_mode == MouseObject && !internal_editing()) { track_canvas->get_window()->set_cursor (*trimmer_cursor); } break; + case LeftFrameHandle: + if (is_drawable() && mouse_mode == MouseObject && !internal_editing()) { + track_canvas->get_window()->set_cursor (*left_side_trim_cursor); + } + break; + + case RightFrameHandle: + if (is_drawable() && mouse_mode == MouseObject && !internal_editing()) { + track_canvas->get_window()->set_cursor (*right_side_trim_cursor); + } + break; + case StartSelectionTrimItem: case EndSelectionTrimItem: @@ -1546,18 +1615,34 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ track_canvas->get_window()->set_cursor (*timebar_cursor); } break; + case FadeInHandleItem: + if (mouse_mode == MouseObject && !internal_editing()) { + ArdourCanvas::SimpleRect *rect = dynamic_cast (item); + if (rect) { + rect->property_fill_color_rgba() = 0; + rect->property_outline_pixels() = 1; + } + track_canvas->get_window()->set_cursor (*fade_in_cursor); + } + break; + case FadeOutHandleItem: - if (mouse_mode == MouseObject) { + if (mouse_mode == MouseObject && !internal_editing()) { ArdourCanvas::SimpleRect *rect = dynamic_cast (item); if (rect) { rect->property_fill_color_rgba() = 0; rect->property_outline_pixels() = 1; } - track_canvas->get_window()->set_cursor (*grabber_cursor); + track_canvas->get_window()->set_cursor (*fade_out_cursor); + } + break; + case FeatureLineItem: + { + ArdourCanvas::SimpleLine *line = dynamic_cast (item); + line->property_color_rgba() = 0xFF0000FF; } break; - default: break; } @@ -1582,7 +1667,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ break; } - return false; + return ret; } bool @@ -1594,6 +1679,7 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ Location *loc; RegionView* rv; bool is_start; + bool ret = true; switch (item_type) { case ControlPointItem: @@ -1612,6 +1698,8 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ break; case RegionViewNameHighlight: + case LeftFrameHandle: + case RightFrameHandle: case StartSelectionTrimItem: case EndSelectionTrimItem: case PlayheadCursorItem: @@ -1699,12 +1787,18 @@ Editor::leave_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ Glib::signal_idle().connect (sigc::mem_fun(*this, &Editor::left_automation_track)); } break; + case FeatureLineItem: + { + ArdourCanvas::SimpleLine *line = dynamic_cast (item); + line->property_color_rgba() = (guint) ARDOUR_UI::config()->canvasvar_ZeroLine.get();; + } + break; default: break; } - return false; + return ret; } gint @@ -1835,7 +1929,7 @@ Editor::motion_handler (ArdourCanvas::Item* /*item*/, GdkEvent* event, bool from if (_drags->active ()) { handled = _drags->motion_handler (event, from_autoscroll); } - + if (!handled) { return false; } @@ -1997,7 +2091,7 @@ Editor::show_verbose_time_cursor (nframes64_t frame, double offset, double xpos, mins = frame / (frame_rate * 60); frame = frame % (frame_rate * 60); secs = (float) frame / (float) frame_rate; - snprintf (buf, sizeof (buf), "%02" PRId32 ":%02" PRId32 ":%.4f", hours, mins, secs); + snprintf (buf, sizeof (buf), "%02" PRId32 ":%02" PRId32 ":%07.4f", hours, mins, secs); break; default: @@ -2078,7 +2172,7 @@ Editor::show_verbose_duration_cursor (nframes64_t start, nframes64_t end, double mins = distance / (frame_rate * 60); distance = distance % (frame_rate * 60); secs = (float) distance / (float) frame_rate; - snprintf (buf, sizeof (buf), "%02" PRId32 ":%02" PRId32 ":%.4f", hours, mins, secs); + snprintf (buf, sizeof (buf), "%02" PRId32 ":%02" PRId32 ":%07.4f", hours, mins, secs); break; default: @@ -2569,36 +2663,19 @@ Editor::set_internal_edit (bool yn) mouse_select_button.set_image (*(manage (new Image (::get_icon("midi_tool_pencil"))))); mouse_select_button.get_image ()->show (); ARDOUR_UI::instance()->tooltips().set_tip (mouse_select_button, _("Draw/Edit MIDI Notes")); - - for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { - MidiTimeAxisView* mtv = dynamic_cast (*i); - if (mtv) { - mtv->start_step_editing (); - } - } - - for (TrackSelection::iterator i = selection->tracks.begin(); i != selection->tracks.end(); ++i) { - (*i)->hide_selection (); - } - - start_step_editing (); set_canvas_cursor (); + /* deselect everything to avoid confusion when e.g. we can't now cut a previously selected + region because cut means "cut note" rather than "cut region". + */ + selection->clear (); + } else { mouse_select_button.set_image (*(manage (new Image (::get_icon("tool_range"))))); mouse_select_button.get_image ()->show (); ARDOUR_UI::instance()->tooltips().set_tip (mouse_select_button, _("Select/Move Ranges")); - stop_step_editing (); - - for (TrackViewList::iterator i = track_views.begin(); i != track_views.end(); ++i) { - MidiTimeAxisView* mtv = dynamic_cast (*i); - if (mtv) { - mtv->stop_step_editing (); - } - } - - mouse_mode_toggled (mouse_mode); + mouse_mode_toggled (mouse_mode); // sets cursor } } @@ -2654,3 +2731,12 @@ Editor::effective_mouse_mode () const return mouse_mode; } + +void +Editor::remove_midi_note (ArdourCanvas::Item* item, GdkEvent *) +{ + ArdourCanvas::CanvasNoteEvent* e = dynamic_cast (item); + assert (e); + + e->region_view().delete_note (e->note ()); +}