diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 47e12cb12e..3415435aad 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -1448,6 +1448,7 @@ class Editor : public PublicEditor, public PBD::ScopedConnectionList, public ARD bool canvas_feature_line_event (GdkEvent* event, ArdourCanvas::Item*, RegionView*); bool canvas_stream_view_event (GdkEvent* event,ArdourCanvas::Item*, RouteTimeAxisView*); bool canvas_marker_event (GdkEvent* event,ArdourCanvas::Item*, Marker*); + bool canvas_range_marker_handle_event (GdkEvent* event,ArdourCanvas::Item*, bool leftside); bool canvas_zoom_rect_event (GdkEvent* event,ArdourCanvas::Item*); bool canvas_tempo_marker_event (GdkEvent* event,ArdourCanvas::Item*, TempoMarker*); bool canvas_meter_marker_event (GdkEvent* event,ArdourCanvas::Item*, MeterMarker*); diff --git a/gtk2_ardour/editor_canvas_events.cc b/gtk2_ardour/editor_canvas_events.cc index 3001abaaef..03317c6605 100644 --- a/gtk2_ardour/editor_canvas_events.cc +++ b/gtk2_ardour/editor_canvas_events.cc @@ -47,6 +47,7 @@ #include "midi_time_axis.h" #include "editor_regions.h" #include "verbose_cursor.h" +#include "mouse_cursors.h" #include "i18n.h" @@ -892,6 +893,30 @@ Editor::canvas_marker_event (GdkEvent *event, ArdourCanvas::Item* item, Marker* return typed_event (item, event, MarkerItem); } +bool +Editor::canvas_range_marker_handle_event (GdkEvent *event, ArdourCanvas::Item* item, bool left_side) +{ + switch (event->type) { + case GDK_ENTER_NOTIFY: + if (left_side) { + push_canvas_cursor (cursors()->left_side_trim); + } else { + push_canvas_cursor (cursors()->right_side_trim); + } + break; + + case GDK_LEAVE_NOTIFY: + pop_canvas_cursor (); + break; + + default: + return typed_event (item, event, (left_side ? LeftDragHandle : RightDragHandle)); + break; + } + + return false; +} + bool Editor::canvas_marker_bar_event (GdkEvent *event, ArdourCanvas::Item* item) { diff --git a/gtk2_ardour/editor_drag.cc b/gtk2_ardour/editor_drag.cc index c0d844a47d..395fda4330 100644 --- a/gtk2_ardour/editor_drag.cc +++ b/gtk2_ardour/editor_drag.cc @@ -3149,14 +3149,21 @@ FadeOutDrag::aborted (bool) sigc::connection MarkerDrag::timeout_connection; -MarkerDrag::MarkerDrag (Editor* e, ArdourCanvas::Item* i) +MarkerDrag::MarkerDrag (Editor* e, ArdourCanvas::Item* i, Type t) : Drag (e, i) - , type (Move) + , type (t) { DEBUG_TRACE (DEBUG::Drags, "New MarkerDrag\n"); _marker = reinterpret_cast (_item->get_data ("marker")); - assert (_marker); + assert (_marker); + + Location *location = _marker->location(); + + if (location && location->is_mark()) { + /* Enforce this */ + type = Move; + } } MarkerDrag::~MarkerDrag () @@ -3184,30 +3191,11 @@ MarkerDrag::start_grab (GdkEvent* event, Gdk::Cursor* cursor) boost::optional ro = _marker->the_item().bounding_box(); assert (ro); ArdourCanvas::Rect r (*ro); - - r = _marker->the_item().item_to_canvas (r); - - if (r.width() > 50.0) { - if (abs (grab_x() - r.x0) < 20.0) { - type = TrimLeft; - } else if (abs (grab_x() - r.x1) < 20.0) { - type = TrimRight; - } else { - type = Move; - } - } else { - type = Move; - } - Location *location = _marker->location(); _editor->_dragging_edit_point = true; + Location *location = _marker->location(); if (location) { - - if (location->is_mark()) { - type = Move; - } - show_drag_text (location); } diff --git a/gtk2_ardour/editor_drag.h b/gtk2_ardour/editor_drag.h index 1cfc4961b6..7dbbe71a04 100644 --- a/gtk2_ardour/editor_drag.h +++ b/gtk2_ardour/editor_drag.h @@ -750,7 +750,13 @@ public: class MarkerDrag : public Drag { public: - MarkerDrag (Editor *, ArdourCanvas::Item *); + enum Type { + TrimLeft, + TrimRight, + Move + }; + + MarkerDrag (Editor *, ArdourCanvas::Item *, Type); ~MarkerDrag (); void start_grab (GdkEvent *, Gdk::Cursor* c = 0); @@ -767,15 +773,9 @@ public: } private: - enum Type { - TrimLeft, - TrimRight, - Move - }; - Marker* _marker; ///< marker being dragged Type type; - + struct CopiedLocationMarkerInfo { ARDOUR::Location* location; std::vector markers; diff --git a/gtk2_ardour/editor_items.h b/gtk2_ardour/editor_items.h index 62ebb0a12b..657582deca 100644 --- a/gtk2_ardour/editor_items.h +++ b/gtk2_ardour/editor_items.h @@ -63,7 +63,9 @@ enum ItemType { SamplesRulerItem, DropZoneItem, ClockRulerItem, - + LeftDragHandle, + RightDragHandle, + /* don't remove this */ NoItem diff --git a/gtk2_ardour/editor_markers.cc b/gtk2_ardour/editor_markers.cc index 49af3f9876..6045d1250d 100644 --- a/gtk2_ardour/editor_markers.cc +++ b/gtk2_ardour/editor_markers.cc @@ -1156,6 +1156,7 @@ Editor::update_loop_range_view () if (lam) { lam->start->set_color (ARDOUR_UI::instance()->config()->get_canvasvar_LoopRangeMarkerActive()); + lam->start->set_trim_active (true); } } else { @@ -1163,6 +1164,7 @@ Editor::update_loop_range_view () if (lam) { lam->start->set_color (ARDOUR_UI::instance()->config()->get_canvasvar_LoopRangeMarkerInactive()); + lam->start->set_trim_active (false); } } } diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index 936ffc07a5..0f1849329c 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -635,15 +635,23 @@ Editor::button_press_handler_1 (ArdourCanvas::Item* item, GdkEvent* event, ItemT _drags->set (new RangeMarkerBarDrag (this, clock_ruler, RangeMarkerBarDrag::CreateLoopMarker), event); return true; } else { - _drags->set (new MarkerDrag (this, item), event); + _drags->set (new MarkerDrag (this, item, MarkerDrag::Move), event); return true; } } } - _drags->set (new MarkerDrag (this, item), event); + _drags->set (new MarkerDrag (this, item, MarkerDrag::Move), event); } return true; + case LeftDragHandle: + _drags->set (new MarkerDrag (this, item, MarkerDrag::TrimLeft), event); + break; + + case RightDragHandle: + _drags->set (new MarkerDrag (this, item, MarkerDrag::TrimRight), event); + break; + case TempoMarkerItem: { TempoMarker* m = reinterpret_cast (item->get_data ("marker")); @@ -1837,7 +1845,7 @@ Editor::enter_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item_ break; case MarkerItem: - case MeterMarkerItem: + case MeterMarkerItem: case TempoMarkerItem: break; diff --git a/gtk2_ardour/marker.cc b/gtk2_ardour/marker.cc index 572a4d80a8..bc84f00d57 100644 --- a/gtk2_ardour/marker.cc +++ b/gtk2_ardour/marker.cc @@ -103,6 +103,16 @@ RangeMarker::RangeMarker (ARDOUR::Location* l, PublicEditor& editor, ArdourCanva { assert (start < end); + left_drag_handle = new ArdourCanvas::Rectangle (group); + left_drag_handle->set_outline (false); + left_drag_handle->set_fill (false); + left_drag_handle->Event.connect (sigc::bind (sigc::mem_fun (editor, &PublicEditor::canvas_range_marker_handle_event), group, true)); + + right_drag_handle = new ArdourCanvas::Rectangle (group); + right_drag_handle->set_outline (false); + right_drag_handle->set_fill (false); + right_drag_handle->Event.connect (sigc::bind (sigc::mem_fun (editor, &PublicEditor::canvas_range_marker_handle_event), group, false)); + /* Marker::Marker calls these but will not have used our versions since it is a constructor. */ @@ -111,6 +121,7 @@ RangeMarker::RangeMarker (ARDOUR::Location* l, PublicEditor& editor, ArdourCanva use_color (); setup_name_display (); + /* our appearance depends on some backend parameters, so pick up changes as necessary */ Config->ParameterChanged.connect (parameter_connection, invalidator (*this), boost::bind (&RangeMarker::parameter_changed, this, _1), gui_context()); @@ -206,6 +217,29 @@ RangeMarker::_set_position (framepos_t start, framepos_t end) if (_name_item) { _name_item->clamp_width (pixel_width - _label_offset); } + + double handle_width = min (pixel_width/2.0, 10.0); + + if (left_drag_handle) { + ArdourCanvas::Rect r; + r.x0 = 0; + r.x1 = handle_width; + r.y0 = 0; + r.y1 = _height; + + left_drag_handle->set (r); + } + + if (right_drag_handle) { + ArdourCanvas::Rect r; + r.x0 = pixel_width - handle_width; + r.x1 = pixel_width; + r.y0 = 0; + r.y1 = _height; + + right_drag_handle->set (r); + } + } Marker::_set_position (start, end); @@ -252,8 +286,8 @@ RangeMarker::setup_line () _start_handler->set_outline_what (ArdourCanvas::Rectangle::What (ArdourCanvas::Rectangle::NOTHING)); } - _start_handler->set_x0 (0); - _start_handler->set_y0 (0); + _start_handler->set_x0 (0); +_start_handler->set_y0 (0); _start_handler->set_x1 (handler_size); _start_handler->set_y1 (handler_size); @@ -321,6 +355,8 @@ Marker::Marker (ARDOUR::Location* l, PublicEditor& ed, ArdourCanvas::Container& , _scene_change_rect (0) , _scene_change_text (0) , _marker_lock_text (0) + , left_drag_handle (0) + , right_drag_handle (0) , frame_position (start_pos) , _type (type) , _shown (false) @@ -330,6 +366,7 @@ Marker::Marker (ARDOUR::Location* l, PublicEditor& ed, ArdourCanvas::Container& , _right_label_limit (DBL_MAX) , _label_offset (0) , _have_scene_change (l ? l->scene_change() : false) + { unit_position = editor.sample_to_pixel (frame_position); @@ -816,6 +853,17 @@ Marker::set_has_scene_change (bool yn) setup_name_display (); } +void +Marker::set_trim_active (bool yn) +{ + if (left_drag_handle) { + left_drag_handle->set_ignore_events (!yn); + } + if (right_drag_handle) { + right_drag_handle->set_ignore_events (!yn); + } +} + /***********************************************************************/ TempoMarker::TempoMarker (PublicEditor& editor, ArdourCanvas::Container& parent, double height, guint32 rgba, const string& text, diff --git a/gtk2_ardour/marker.h b/gtk2_ardour/marker.h index a326ce678a..9ed6686ad2 100644 --- a/gtk2_ardour/marker.h +++ b/gtk2_ardour/marker.h @@ -111,6 +111,8 @@ class Marker : public sigc::trackable bool label_on_left () const; + void set_trim_active (bool); + static double marker_height() { return _marker_height; } static const char * default_new_marker_prefix; @@ -130,6 +132,8 @@ class Marker : public sigc::trackable ArdourCanvas::Rectangle* _scene_change_rect; ArdourCanvas::Text* _scene_change_text; ArdourCanvas::Text* _marker_lock_text; + ArdourCanvas::Rectangle* left_drag_handle; + ArdourCanvas::Rectangle* right_drag_handle; std::string _name; double unit_position; diff --git a/gtk2_ardour/public_editor.h b/gtk2_ardour/public_editor.h index 6b2eecf278..18de1cc205 100644 --- a/gtk2_ardour/public_editor.h +++ b/gtk2_ardour/public_editor.h @@ -348,6 +348,7 @@ class PublicEditor : public Gtk::Window, public PBD::StatefulDestructible, publi virtual bool canvas_feature_line_event (GdkEvent* event, ArdourCanvas::Item*, RegionView*) = 0; virtual bool canvas_stream_view_event (GdkEvent* event, ArdourCanvas::Item*, RouteTimeAxisView*) = 0; virtual bool canvas_marker_event (GdkEvent* event, ArdourCanvas::Item*, Marker*) = 0; + virtual bool canvas_range_marker_handle_event (GdkEvent* event, ArdourCanvas::Item*, bool leftside) = 0; virtual bool canvas_videotl_bar_event (GdkEvent* event, ArdourCanvas::Item*) = 0; virtual bool canvas_zoom_rect_event (GdkEvent* event, ArdourCanvas::Item*) = 0; virtual bool canvas_tempo_marker_event (GdkEvent* event, ArdourCanvas::Item*, TempoMarker*) = 0;