From 1651446e0f3b9a2c8ee8fd8aacd15941659b3474 Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Mon, 12 May 2014 12:07:46 -0700 Subject: [PATCH] Drag the entire audio selection when Alt is held down Closes #691. --- src/audio_display.cpp | 6 ++--- src/audio_timing.h | 2 +- src/audio_timing_dialogue.cpp | 43 +++++++++++++++++++++++++++-------- src/audio_timing_karaoke.cpp | 4 ++-- 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/src/audio_display.cpp b/src/audio_display.cpp index 481cc0616..618f9232a 100644 --- a/src/audio_display.cpp +++ b/src/audio_display.cpp @@ -1075,9 +1075,9 @@ void AudioDisplay::OnMouseEvent(wxMouseEvent& event) if (event.LeftDown() || event.RightDown()) { const int timepos = TimeFromRelativeX(mouse_x); - std::vector markers = event.LeftDown() ? - timing->OnLeftClick(timepos, event.CmdDown(), drag_sensitivity, snap_sensitivity) : - timing->OnRightClick(timepos, event.CmdDown(), drag_sensitivity, snap_sensitivity); + std::vector markers = event.LeftDown() + ? timing->OnLeftClick(timepos, event.CmdDown(), event.AltDown(), drag_sensitivity, snap_sensitivity) + : timing->OnRightClick(timepos, event.CmdDown(), drag_sensitivity, snap_sensitivity); // Clicking should never result in the audio display scrolling ScrollPixelToLeft(old_scroll_pos); diff --git a/src/audio_timing.h b/src/audio_timing.h index a755e3228..e20bcef37 100644 --- a/src/audio_timing.h +++ b/src/audio_timing.h @@ -154,7 +154,7 @@ public: /// @param snap_range Maximum snapping range in milliseconds /// @return All audio markers at the clicked position which are eligible /// to be dragged, if any. - virtual std::vector OnLeftClick(int ms, bool ctrl_down, int sensitivity, int snap_range) = 0; + virtual std::vector OnLeftClick(int ms, bool ctrl_down, bool alt_down, int sensitivity, int snap_range) = 0; /// @brief The user pressed the right mouse button on the audio /// @param ms The time in milliseconds the user clicked diff --git a/src/audio_timing_dialogue.cpp b/src/audio_timing_dialogue.cpp index cbc9dec34..9c20362fb 100644 --- a/src/audio_timing_dialogue.cpp +++ b/src/audio_timing_dialogue.cpp @@ -214,7 +214,8 @@ public: /// Get this line's markers /// @param c Vector to add the markers to - void GetMarkers(std::vector *c) const + template + void GetMarkers(Container *c) const { c->push_back(left_marker); c->push_back(right_marker); @@ -325,6 +326,9 @@ class AudioTimingControllerDialogue final : public AudioTimingController { /// The owning project context agi::Context *context; + /// The marker which was clicked on for relative shifting in alt-click mode + DialogueTimingMarker *clicked_marker = nullptr; + /// Autocommit option const agi::OptionValue *auto_commit = OPT_GET("Audio/Auto/Commit"); const agi::OptionValue *inactive_line_mode = OPT_GET("Audio/Inactive Lines Display Mode"); @@ -400,7 +404,7 @@ public: void ModifyLength(int delta, bool shift_following) override; void ModifyStart(int delta) override; bool IsNearbyMarker(int ms, int sensitivity) const override; - std::vector OnLeftClick(int ms, bool ctrl_down, int sensitivity, int snap_range) override; + std::vector OnLeftClick(int ms, bool ctrl_down, bool alt_down, int sensitivity, int snap_range) override; std::vector OnRightClick(int ms, bool, int sensitivity, int snap_range) override; void OnMarkerDrag(std::vector const& markers, int new_position, int snap_range) override; @@ -609,11 +613,13 @@ bool AudioTimingControllerDialogue::IsNearbyMarker(int ms, int sensitivity) cons return active_line.ContainsMarker(TimeRange(ms-sensitivity, ms+sensitivity)); } -std::vector AudioTimingControllerDialogue::OnLeftClick(int ms, bool ctrl_down, int sensitivity, int snap_range) +std::vector AudioTimingControllerDialogue::OnLeftClick(int ms, bool ctrl_down, bool alt_down, int sensitivity, int snap_range) { assert(sensitivity >= 0); assert(snap_range >= 0); + clicked_marker = nullptr; + std::vector ret; DialogueTimingMarker *left = active_line.GetLeftMarker(); @@ -642,9 +648,16 @@ std::vector AudioTimingControllerDialogue::OnLeftClick(int ms, boo // The use of GetPosition here is important, as otherwise it'll start // after lines ending at the same time as the active line begins auto it = boost::lower_bound(markers, clicked->GetPosition(), marker_ptr_cmp()); - for(; it != markers.end() && !(*clicked < **it); ++it) + for (; it != markers.end() && !(*clicked < **it); ++it) ret.push_back(*it); } + else if (alt_down) + { + clicked_marker = clicked; + active_line.GetMarkers(&ret); + for (auto const& line : selected_lines) + line.GetMarkers(&ret); + } else ret.push_back(clicked); @@ -676,6 +689,10 @@ void AudioTimingControllerDialogue::UpdateSelection() void AudioTimingControllerDialogue::SetMarkers(std::vector const& upd_markers, int ms) { + if (upd_markers.empty()) return; + + int shift = clicked_marker ? ms - *clicked_marker : 0; + // Since we're moving markers, the sorted list of markers will need to be // resorted. To avoid resorting the entire thing, find the subrange that // is effected. @@ -683,19 +700,25 @@ void AudioTimingControllerDialogue::SetMarkers(std::vector const& int max_ms = ms; for (AudioMarker *upd_marker : upd_markers) { - DialogueTimingMarker *marker = static_cast(upd_marker); - min_ms = std::min(*marker, min_ms); - max_ms = std::max(*marker, max_ms); + auto marker = static_cast(upd_marker); + if (shift < 0) { + min_ms = std::min(*marker + shift, min_ms); + max_ms = std::max(*marker, max_ms); + } + else { + min_ms = std::min(*marker, min_ms); + max_ms = std::max(*marker + shift, max_ms); + } } auto begin = boost::lower_bound(markers, min_ms, marker_ptr_cmp()); auto end = upper_bound(begin, markers.end(), max_ms, marker_ptr_cmp()); // Update the markers - for (AudioMarker *upd_marker : upd_markers) + for (auto upd_marker : upd_markers) { - DialogueTimingMarker *marker = static_cast(upd_marker); - marker->SetPosition(ms); + auto marker = static_cast(upd_marker); + marker->SetPosition(clicked_marker ? *marker + shift : ms); modified_lines.insert(marker->GetLine()); } diff --git a/src/audio_timing_karaoke.cpp b/src/audio_timing_karaoke.cpp index 1b1527c31..a7eeac3af 100644 --- a/src/audio_timing_karaoke.cpp +++ b/src/audio_timing_karaoke.cpp @@ -140,7 +140,7 @@ public: void ModifyLength(int delta, bool shift_following) override; void ModifyStart(int delta) override; bool IsNearbyMarker(int ms, int sensitivity) const override; - std::vector OnLeftClick(int ms, bool, int sensitivity, int) override; + std::vector OnLeftClick(int ms, bool, bool, int sensitivity, int) override; std::vector OnRightClick(int ms, bool, int, int) override; void OnMarkerDrag(std::vector const& marker, int new_position, int) override; @@ -347,7 +347,7 @@ static std::vector copy_ptrs(In &vec, size_t start, size_t end) { return ret; } -std::vector AudioTimingControllerKaraoke::OnLeftClick(int ms, bool ctrl_down, int sensitivity, int) { +std::vector AudioTimingControllerKaraoke::OnLeftClick(int ms, bool ctrl_down, bool, int sensitivity, int) { TimeRange range(ms - sensitivity, ms + sensitivity); size_t syl = distance(markers.begin(), lower_bound(markers.begin(), markers.end(), ms));