From 73dd9d37e7d715e0d78c0e51569968f9494dac7f Mon Sep 17 00:00:00 2001 From: David Robillard Date: Mon, 7 Jan 2008 21:12:29 +0000 Subject: [PATCH] Merge with 2.0-ongoing R2653. git-svn-id: svn://localhost/ardour2/trunk@2837 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/audio_region_view.cc | 6 ++- gtk2_ardour/editor.cc | 9 ++++ gtk2_ardour/editor.h | 4 ++ gtk2_ardour/editor_mouse.cc | 61 +++++++++++++++++++++------- gtk2_ardour/editor_ops.cc | 22 ++++++++++ gtk2_ardour/region_view.cc | 70 +++++++++++++++++++++++--------- gtk2_ardour/region_view.h | 2 + 7 files changed, 138 insertions(+), 36 deletions(-) diff --git a/gtk2_ardour/audio_region_view.cc b/gtk2_ardour/audio_region_view.cc index 5aa60cb639..f101905012 100644 --- a/gtk2_ardour/audio_region_view.cc +++ b/gtk2_ardour/audio_region_view.cc @@ -410,12 +410,14 @@ AudioRegionView::region_muted () void AudioRegionView::set_y_position_and_height (double y, double h) { - RegionView::set_y_position_and_height(y, h - 1); + //RegionView::set_y_position_and_height(y, h - 1); + RegionView::set_height (height); + + const uint32_t wcnt = waves.size(); _y_position = y; _height = h; - uint32_t const wcnt = waves.size(); for (uint32_t n = 0; n < wcnt; ++n) { double ht; diff --git a/gtk2_ardour/editor.cc b/gtk2_ardour/editor.cc index a158bb73e9..e0f8b24b53 100644 --- a/gtk2_ardour/editor.cc +++ b/gtk2_ardour/editor.cc @@ -171,6 +171,7 @@ Gdk::Cursor* Editor::midi_select_cursor = 0; Gdk::Cursor* Editor::midi_erase_cursor = 0; Gdk::Cursor* Editor::wait_cursor = 0; Gdk::Cursor* Editor::timebar_cursor = 0; +Gdk::Cursor* Editor::transparent_cursor = 0; void show_me_the_size (Requisition* r, const char* what) @@ -1311,6 +1312,14 @@ Editor::build_cursors () speaker_cursor = new Gdk::Cursor (source, mask, ffg, fbg, speaker_cursor_x_hot, speaker_cursor_y_hot); } + { + RefPtr bits; + char pix[4] = { 0, 0, 0, 0 }; + bits = Bitmap::create (pix, 2, 2); + Gdk::Color c; + transparent_cursor = new Gdk::Cursor (bits, bits, c, c, 0, 0); + } + grabber_cursor = new Gdk::Cursor (HAND2); cross_hair_cursor = new Gdk::Cursor (CROSSHAIR); trimmer_cursor = new Gdk::Cursor (SB_H_DOUBLE_ARROW); diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index bd0f91ad21..faefda51ab 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -907,6 +907,7 @@ class Editor : public PublicEditor static Gdk::Cursor* midi_erase_cursor; static Gdk::Cursor* wait_cursor; static Gdk::Cursor* timebar_cursor; + static Gdk::Cursor* transparent_cursor; static void build_cursors (); @@ -1155,6 +1156,8 @@ class Editor : public PublicEditor bool _scrubbing; double last_scrub_x; int scrubbing_direction; + int scrub_reversals; + int scrub_reverse_distance; void keyboard_selection_begin (); void keyboard_selection_finish (bool add); @@ -1983,6 +1986,7 @@ class Editor : public PublicEditor TimeAxisView* entered_track; RegionView* entered_regionview; + void ensure_entered_selected (); bool clear_entered_track; gint left_track_canvas (GdkEventCrossing*); void set_entered_track (TimeAxisView*); diff --git a/gtk2_ardour/editor_mouse.cc b/gtk2_ardour/editor_mouse.cc index 47bb35325e..78fdf5d2b2 100644 --- a/gtk2_ardour/editor_mouse.cc +++ b/gtk2_ardour/editor_mouse.cc @@ -649,8 +649,7 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp } else if (Keyboard::modifier_state_equals (event->button.state, Keyboard::Control)) { /* grab selection for moving */ start_selection_op (item, event, SelectionMove); - } - else { + } else { /* this was debated, but decided the more common action was to make a new selection */ start_selection_op (item, event, CreateSelection); @@ -810,8 +809,11 @@ Editor::button_press_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemTyp case MouseAudition: _scrubbing = true; + scrub_reversals = 0; + scrub_reverse_distance = 0; last_scrub_x = event->button.x; scrubbing_direction = 0; + track_canvas.get_window()->set_cursor (*transparent_cursor); /* rest handled in motion & release */ break; @@ -1144,6 +1146,7 @@ Editor::button_release_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemT case MouseAudition: _scrubbing = false; + track_canvas.get_window()->set_cursor (*current_canvas_cursor); if (scrubbing_direction == 0) { /* no drag, just a click */ switch (item_type) { @@ -1548,39 +1551,67 @@ Editor::motion_handler (ArdourCanvas::Item* item, GdkEvent* event, ItemType item scrubbing_direction = 1; } else { - if (last_scrub_x > drag_info.current_pointer_x) { - /* move to the left */ + + /* pointer moved to the left */ if (scrubbing_direction > 0) { + /* we reversed direction to go backwards */ - - session->request_transport_speed (-0.1); - + + scrub_reversals++; + scrub_reverse_distance += (int) (last_scrub_x - drag_info.current_pointer_x); + } else { + /* still moving to the left (backwards) */ - delta = 0.005 * (last_scrub_x - drag_info.current_pointer_x); + scrub_reversals = 0; + scrub_reverse_distance = 0; + + delta = 0.01 * (last_scrub_x - drag_info.current_pointer_x); session->request_transport_speed (session->transport_speed() - delta); } - scrubbing_direction = -1; - } else { - /* move to the right */ + /* pointer moved to the right */ + if (scrubbing_direction < 0) { /* we reversed direction to go forward */ - - session->request_transport_speed (0.1); + + scrub_reversals++; + scrub_reverse_distance += (int) (drag_info.current_pointer_x - last_scrub_x); + } else { /* still moving to the right */ + + scrub_reversals = 0; + scrub_reverse_distance = 0; - delta = 0.005 * (drag_info.current_pointer_x - last_scrub_x); + delta = 0.01 * (drag_info.current_pointer_x - last_scrub_x); session->request_transport_speed (session->transport_speed() + delta); } + } + + /* if there have been more than 2 opposite motion moves detected, or one that moves + back more than 10 pixels, reverse direction + */ + + if (scrub_reversals >= 2 || scrub_reverse_distance > 10) { + + if (scrubbing_direction > 0) { + /* was forwards, go backwards */ + session->request_transport_speed (-0.1); + scrubbing_direction = -1; + } else { + /* was backwards, go forwards */ + session->request_transport_speed (0.1); + scrubbing_direction = 1; + } - scrubbing_direction = 1; + scrub_reverse_distance = 0; + scrub_reversals = 0; } } diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index 8315b3c88a..dd5f2b4599 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -2306,6 +2306,8 @@ Editor::separate_regions_using_location (Location& loc) void Editor::crop_region_to_selection () { + ensure_entered_selected (); + if (!selection->time.empty()) { crop_region_to (selection->time.start(), selection->time.end_frame()); @@ -2329,6 +2331,8 @@ Editor::crop_region_to (nframes_t start, nframes_t end) boost::shared_ptr playlist; TrackSelection* ts; + ensure_entered_selected (); + if (selection->tracks.empty()) { ts = &track_views; } else { @@ -2567,6 +2571,8 @@ Editor::naturalize () void Editor::align (RegionPoint what) { + ensure_entered_selected (); + nframes64_t where = get_preferred_edit_position(); if (!selection->regions.empty()) { @@ -2731,6 +2737,8 @@ Editor::trim_region_to_punch () void Editor::trim_region_to_location (const Location& loc, const char* str) { + ensure_entered_selected (); + RegionSelection& rs (get_regions_for_action ()); begin_reversible_command (str); @@ -3907,6 +3915,8 @@ Editor::toggle_region_opaque () void Editor::set_fade_length (bool in) { + ensure_entered_selected (); + /* we need a region to measure the offset from the start */ RegionView* rv; @@ -4131,6 +4141,8 @@ Editor::set_playhead_cursor () void Editor::split () { + ensure_entered_selected (); + nframes64_t where = get_preferred_edit_position(); if (!selection->regions.empty()) { @@ -4144,3 +4156,13 @@ Editor::split () split_regions_at (where, rs); } } + +void +Editor::ensure_entered_selected () +{ + if (entered_regionview) { + if (find (selection->regions.begin(), selection->regions.end(), entered_regionview) == selection->regions.end()) { + selection->set (entered_regionview); + } + } +} diff --git a/gtk2_ardour/region_view.cc b/gtk2_ardour/region_view.cc index f2d82e0f62..fb715559a1 100644 --- a/gtk2_ardour/region_view.cc +++ b/gtk2_ardour/region_view.cc @@ -70,6 +70,7 @@ RegionView::RegionView (ArdourCanvas::Group* parent, TimeAxisViewItem::ShowFrame)) , _region (r) , sync_mark(0) + , sync_line(0) , editor(0) , current_visible_sync_position(0.0) , valid(false) @@ -102,6 +103,7 @@ RegionView::RegionView (ArdourCanvas::Group* parent, : TimeAxisViewItem (r->name(), *parent, tv, spu, basic_color, r->position(), r->length(), visibility) , _region (r) , sync_mark(0) + , sync_line(0) , editor(0) , current_visible_sync_position(0.0) , valid(false) @@ -119,6 +121,8 @@ RegionView::init (Gdk::Color& basic_color, bool wfd) _enable_display = false; in_destructor = false; wait_for_data = wfd; + sync_mark = 0; + sync_line = 0; compute_colors (basic_color); @@ -128,19 +132,6 @@ RegionView::init (Gdk::Color& basic_color, bool wfd) name_text->set_data ("regionview", this); } - /* an equilateral triangle */ - - ArdourCanvas::Points shape; - shape.push_back (Gnome::Art::Point (-((sync_mark_width-1)/2), 1)); - shape.push_back (Gnome::Art::Point ((sync_mark_width - 1)/2, 1)); - shape.push_back (Gnome::Art::Point (0, sync_mark_width - 1)); - shape.push_back (Gnome::Art::Point (-((sync_mark_width-1)/2), 1)); - - sync_mark = new ArdourCanvas::Polygon (*group); - sync_mark->property_points() = shape; - sync_mark->property_fill_color_rgba() = fill_color; - sync_mark->hide(); - //reset_width_dependent_items ((double) _region->length() / samples_per_unit); if (wfd) @@ -370,6 +361,7 @@ RegionView::set_colors () if (sync_mark) { sync_mark->property_fill_color_rgba() = fill_color; + sync_line->property_fill_color_rgba() = fill_color; } } @@ -444,15 +436,32 @@ RegionView::region_renamed () void RegionView::region_sync_changed () { - if (sync_mark == 0) { - return; - } - int sync_dir; nframes_t sync_offset; sync_offset = _region->sync_offset (sync_dir); + if (sync_offset == 0) { + /* no need for a sync mark */ + if (sync_mark) { + sync_mark->hide(); + sync_line->hide (); + } + return; + } + + if (!sync_mark) { + + /* points set below */ + + sync_mark = new ArdourCanvas::Polygon (*group); + sync_mark->property_fill_color_rgba() = fill_color; + + sync_line = new ArdourCanvas::Line (*group); + sync_line->property_fill_color_rgba() = fill_color; + sync_line->property_width_pixels() = 1; + } + /* this has to handle both a genuine change of position, a change of samples_per_unit, and a change in the bounds of the _region-> */ @@ -460,8 +469,9 @@ RegionView::region_sync_changed () if (sync_offset == 0) { /* no sync mark - its the start of the region */ - + sync_mark->hide(); + sync_line->hide (); } else { @@ -470,6 +480,7 @@ RegionView::region_sync_changed () /* no sync mark - its out of the bounds of the region */ sync_mark->hide(); + sync_line->hide (); } else { @@ -485,8 +496,14 @@ RegionView::region_sync_changed () points.push_back (Gnome::Art::Point (offset, sync_mark_width - 1)); points.push_back (Gnome::Art::Point (offset - ((sync_mark_width-1)/2), 1)); sync_mark->property_points().set_value (points); - sync_mark->show(); + sync_mark->show (); + points.clear (); + points.push_back (Gnome::Art::Point (offset, 0)); + points.push_back (Gnome::Art::Point (offset, _height - NAME_HIGHLIGHT_SIZE)); + + sync_line->property_points().set_value (points); + sync_line->show (); } } } @@ -533,3 +550,18 @@ RegionView::get_fill_color () return fill_color; } +void +RegionView::set_height (double h) +{ + if (sync_line) { + Points points; + int sync_dir; + nframes_t sync_offset; + sync_offset = _region->sync_offset (sync_dir); + double offset = sync_offset / samples_per_unit; + + points.push_back (Gnome::Art::Point (offset, 0)); + points.push_back (Gnome::Art::Point (offset, h - NAME_HIGHLIGHT_SIZE)); + sync_line->property_points().set_value (points); + } +} diff --git a/gtk2_ardour/region_view.h b/gtk2_ardour/region_view.h index 23ac2fcc71..e5822715ca 100644 --- a/gtk2_ardour/region_view.h +++ b/gtk2_ardour/region_view.h @@ -60,6 +60,7 @@ class RegionView : public TimeAxisViewItem void set_valid (bool yn) { valid = yn; } + virtual void set_height (double); virtual void set_samples_per_unit (double); virtual bool set_duration (nframes_t, void*); @@ -124,6 +125,7 @@ class RegionView : public TimeAxisViewItem boost::shared_ptr _region; ArdourCanvas::Polygon* sync_mark; ///< polgyon for sync position + ArdourCanvas::Line* sync_line; ///< polgyon for sync position RegionEditor* editor;