From 6a6c983f1941d318fddbf0fa3e298ef39772c11b Mon Sep 17 00:00:00 2001 From: Thomas Goyne Date: Wed, 18 Sep 2013 15:52:48 -0700 Subject: [PATCH] Add box selection to the move mode of the vector clip tool Closes #1404. --- aegisub/src/visual_tool_vector_clip.cpp | 57 ++++++++++++++++++++++--- aegisub/src/visual_tool_vector_clip.h | 2 + 2 files changed, 54 insertions(+), 5 deletions(-) diff --git a/aegisub/src/visual_tool_vector_clip.cpp b/aegisub/src/visual_tool_vector_clip.cpp index f06878f37..30281421d 100644 --- a/aegisub/src/visual_tool_vector_clip.cpp +++ b/aegisub/src/visual_tool_vector_clip.cpp @@ -32,6 +32,8 @@ #include #include +#include +#include #include /// Button IDs @@ -50,7 +52,7 @@ enum { VisualToolVectorClip::VisualToolVectorClip(VideoDisplay *parent, agi::Context *context) : VisualTool(parent, context) , spline(*this) -, toolBar(0) +, toolBar(nullptr) , mode(0) , inverse(false) { @@ -105,8 +107,19 @@ void VisualToolVectorClip::Draw() { gl.SetLineColour(colour[3], 1.f, 2); gl.SetFillColour(wxColour(0, 0, 0), 0.5f); + // draw the shade over clipped out areas and line showing the clip gl.DrawMultiPolygon(points, start, count, video_pos, video_res, !inverse); + if (mode == 0 && holding && drag_start && mouse_pos) { + // Draw drag-select box + Vector2D top_left = drag_start.Min(mouse_pos); + Vector2D bottom_right = drag_start.Max(mouse_pos); + gl.DrawDashedLine(top_left, Vector2D(top_left.X(), bottom_right.Y()), 6); + gl.DrawDashedLine(Vector2D(top_left.X(), bottom_right.Y()), bottom_right, 6); + gl.DrawDashedLine(bottom_right, Vector2D(bottom_right.X(), top_left.Y()), 6); + gl.DrawDashedLine(Vector2D(bottom_right.X(), top_left.Y()), top_left, 6); + } + Vector2D pt; float t; Spline::iterator highlighted_curve; @@ -246,6 +259,12 @@ bool VisualToolVectorClip::InitializeDrag(Feature *feature) { } bool VisualToolVectorClip::InitializeHold() { + // Box selection + if (mode == 0) { + box_added.clear(); + return true; + } + // Insert line/bicubic if (mode == 1 || mode == 2) { SplineCurve curve; @@ -326,17 +345,45 @@ bool VisualToolVectorClip::InitializeHold() { return true; } - /// @todo box selection? - if (mode == 0) - return false; - // Nothing to do for mode 5 (remove) return false; } +static bool in_box(Vector2D top_left, Vector2D bottom_right, Vector2D p) { + return p.X() >= top_left.X() + && p.X() <= bottom_right.X() + && p.Y() >= top_left.Y() + && p.Y() <= bottom_right.Y(); +} + void VisualToolVectorClip::UpdateHold() { bool needs_save = true; + // Box selection + if (mode == 0) { + std::set boxed_features; + Vector2D p1 = drag_start.Min(mouse_pos); + Vector2D p2 = drag_start.Max(mouse_pos); + for (auto& feature : features) { + if (in_box(p1, p2, feature.pos)) + boxed_features.insert(&feature); + } + + // Keep track of which features were selected by the box selection so + // that only those are deselected if the user is holding ctrl + boost::set_difference(boxed_features, sel_features, + std::inserter(box_added, end(box_added))); + + boost::copy(boxed_features, std::inserter(sel_features, end(sel_features))); + + std::vector to_deselect; + boost::set_difference(box_added, boxed_features, std::back_inserter(to_deselect)); + for (auto feature : to_deselect) + sel_features.erase(feature); + + return; + } + if (mode == 1) { spline.back().EndPoint() = mouse_pos; features.back().pos = mouse_pos; diff --git a/aegisub/src/visual_tool_vector_clip.h b/aegisub/src/visual_tool_vector_clip.h index ceaa72ae1..3fb1cdb92 100644 --- a/aegisub/src/visual_tool_vector_clip.h +++ b/aegisub/src/visual_tool_vector_clip.h @@ -46,6 +46,8 @@ class VisualToolVectorClip : public VisualTool box_added; + /// @brief Set the mode /// @param mode 0-7 void SetMode(int mode);