diff --git a/aegisub/build/libaegisub/libaegisub.vcxproj b/aegisub/build/libaegisub/libaegisub.vcxproj index 9242f69ea..a73a35119 100644 --- a/aegisub/build/libaegisub/libaegisub.vcxproj +++ b/aegisub/build/libaegisub/libaegisub.vcxproj @@ -67,6 +67,7 @@ + diff --git a/aegisub/build/libaegisub/libaegisub.vcxproj.filters b/aegisub/build/libaegisub/libaegisub.vcxproj.filters index 1c487e2cc..a73b5aaf7 100644 --- a/aegisub/build/libaegisub/libaegisub.vcxproj.filters +++ b/aegisub/build/libaegisub/libaegisub.vcxproj.filters @@ -161,6 +161,9 @@ Header Files + + Header Files + diff --git a/aegisub/libaegisub/include/libaegisub/owning_intrusive_list.h b/aegisub/libaegisub/include/libaegisub/owning_intrusive_list.h new file mode 100644 index 000000000..d5b88e1b5 --- /dev/null +++ b/aegisub/libaegisub/include/libaegisub/owning_intrusive_list.h @@ -0,0 +1,92 @@ +// Copyright (c) 2013, Thomas Goyne +// +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// +// Aegisub Project http://www.aegisub.org/ + +#pragma once + +#include + +namespace agi { + +template +class owning_intrusive_list : private boost::intrusive::make_list>::type { + typedef typename boost::intrusive::make_list>::type base; +public: + using base::back; + using base::begin; + using base::cbegin; + using base::cend; + using base::crbegin; + using base::crend; + using base::empty; + using base::end; + using base::front; + using base::insert; + using base::iterator_to; + using base::merge; + using base::push_back; + using base::push_front; + using base::rbegin; + using base::rend; + using base::reverse; + using base::s_iterator_to; + using base::shift_backwards; + using base::shift_forward; + using base::size; + using base::sort; + using base::splice; + using base::swap; + + using typename base::const_node_ptr; + using typename base::const_pointer; + using typename base::const_reverse_iterator; + using typename base::node; + using typename base::node_algorithms; + using typename base::node_ptr; + using typename base::node_traits; + using typename base::pointer; + using typename base::reference; + using typename base::reverse_iterator; + using typename base::size_type; + using typename base::value_type; + using typename base::iterator; + using typename base::const_iterator; + using typename base::const_reference; + using typename base::difference_type; + + iterator erase(const_iterator b, const_iterator e) { return this->erase_and_dispose(b, e, [](T *e) { delete e; }); } + iterator erase(const_iterator b, const_iterator e, difference_type n) { return this->erase_and_dispose(b, e, n, [](T *e) { delete e; }); } + iterator erase(const_iterator i) { return this->erase_and_dispose(i, [](T *e) { delete e; }); } + void clear() { this->clear_and_dispose([](T *e) { delete e; }); } + void pop_back() { this->pop_back_and_dispose([](T *e) { delete e; }); } + void pop_front() { this->pop_front_and_dispose([](T *e) { delete e; }); } + void remove(const_reference value) { return this->remove_and_dispose(value, [](T *e) { delete e; }); } + void unique() { this->unique_and_dispose([](T *e) { delete e; }); } + + template void remove_if(Pred&& pred) { + this->remove_if_and_dispose(std::forward(pred), [](T *e) { delete e; }); + } + + template void unique(BinaryPredicate&& pred) { + this->unique_and_dispose(std::forward(pred), [](T *e) { delete e; }); + } + + ~owning_intrusive_list() { + clear(); + } +}; + +} + diff --git a/aegisub/src/visual_feature.cpp b/aegisub/src/visual_feature.cpp index 250ba1d61..2a94edd89 100644 --- a/aegisub/src/visual_feature.cpp +++ b/aegisub/src/visual_feature.cpp @@ -40,7 +40,7 @@ VisualDraggableFeature::VisualDraggableFeature() : type(DRAG_NONE) , layer(0) -, line(0) +, line(nullptr) { } diff --git a/aegisub/src/visual_feature.h b/aegisub/src/visual_feature.h index 425c43f26..ef4c935b5 100644 --- a/aegisub/src/visual_feature.h +++ b/aegisub/src/visual_feature.h @@ -36,6 +36,8 @@ #include "vector2d.h" +#include + class OpenGLWrapper; class AssDialogue; @@ -54,7 +56,7 @@ enum DraggableFeatureType { /// /// By itself this class doesn't do much. It mostly just draws itself at a /// specified position and performs hit-testing. -class VisualDraggableFeature { +class VisualDraggableFeature : public boost::intrusive::make_list_base_hook>::type { Vector2D start; ///< position before the last drag operation began public: diff --git a/aegisub/src/visual_tool.cpp b/aegisub/src/visual_tool.cpp index cec2e15a0..82c87105d 100644 --- a/aegisub/src/visual_tool.cpp +++ b/aegisub/src/visual_tool.cpp @@ -1,4 +1,4 @@ -// Copyright (c) 2011, Thomas Goyne +// Copyright (c) 2013, Thomas Goyne // // Permission to use, copy, modify, and distribute this software for any // purpose with or without fee is hereby granted, provided that the above @@ -43,7 +43,12 @@ using std::placeholders::_1; -const wxColour VisualToolBase::colour[4] = {wxColour(106,32,19), wxColour(255,169,40), wxColour(255,253,185), wxColour(187,0,0)}; +const wxColour VisualToolBase::colour[] = { + wxColour(106,32,19), + wxColour(255,169,40), + wxColour(255,253,185), + wxColour(187,0,0) +}; VisualToolBase::VisualToolBase(VideoDisplay *parent, agi::Context *context) : c(context) @@ -165,8 +170,8 @@ template VisualTool::VisualTool(VideoDisplay *parent, agi::Context *context) : VisualToolBase(parent, context) , sel_changed(false) +, active_feature(nullptr) { - active_feature = features.begin(); } template @@ -179,30 +184,21 @@ void VisualTool::OnMouseEvent(wxMouseEvent &event) { mouse_pos = event.GetPosition(); - bool need_render = false; - if (event.Leaving()) { mouse_pos = Vector2D(); parent->Render(); return; } - if (event.Entering() && OPT_GET("Tool/Visual/Autohide")->GetBool()) - need_render = true; - if (!dragging) { - feature_iterator prev_feature = active_feature; - int max_layer = INT_MIN; - active_feature = features.end(); - for (feature_iterator cur = features.begin(); cur != features.end(); ++cur) { - if (cur->IsMouseOver(mouse_pos) && cur->layer >= max_layer) { - active_feature = cur; - max_layer = cur->layer; + active_feature = nullptr; + for (auto& feature : features) { + if (feature.IsMouseOver(mouse_pos) && feature.layer >= max_layer) { + active_feature = &feature; + max_layer = feature.layer; } } - - need_render |= active_feature != prev_feature; } if (dragging) { @@ -213,14 +209,13 @@ void VisualTool::OnMouseEvent(wxMouseEvent &event) { for (auto sel : sel_features) UpdateDrag(sel); Commit(); - need_render = true; } // end drag else { dragging = false; // mouse didn't move, fiddle with selection - if (active_feature != features.end() && !active_feature->HasMoved()) { + if (active_feature && !active_feature->HasMoved()) { // Don't deselect stuff that was selected in this click's mousedown event if (!sel_changed) { if (ctrl_down) @@ -230,7 +225,7 @@ void VisualTool::OnMouseEvent(wxMouseEvent &event) { } } - active_feature = features.end(); + active_feature = nullptr; parent->ReleaseMouse(); parent->SetFocus(); } @@ -244,7 +239,6 @@ void VisualTool::OnMouseEvent(wxMouseEvent &event) { } UpdateHold(); - need_render = true; Commit(); } @@ -252,7 +246,7 @@ void VisualTool::OnMouseEvent(wxMouseEvent &event) { drag_start = mouse_pos; // start drag - if (active_feature != features.end()) { + if (active_feature) { if (!sel_features.count(active_feature)) { sel_changed = true; SetSelection(active_feature, !ctrl_down); @@ -276,7 +270,6 @@ void VisualTool::OnMouseEvent(wxMouseEvent &event) { SubtitleSelection sel; sel.insert(c->selectionController->GetActiveLine()); c->selectionController->SetSelectedSet(sel); - need_render = true; } if (active_line && InitializeHold()) { holding = true; @@ -288,8 +281,7 @@ void VisualTool::OnMouseEvent(wxMouseEvent &event) { if (active_line && left_double) OnDoubleClick(); - //if (need_render) - parent->Render(); + parent->Render(); // Only coalesce the changes made in a single drag if (!event.LeftIsDown()) @@ -299,19 +291,19 @@ void VisualTool::OnMouseEvent(wxMouseEvent &event) { template void VisualTool::DrawAllFeatures() { gl.SetLineColour(colour[0], 1.0f, 2); - for (feature_iterator cur = features.begin(); cur != features.end(); ++cur) { + for (auto& feature : features) { int fill = 1; - if (cur == active_feature) + if (&feature == active_feature) fill = 2; - else if (sel_features.count(cur)) + else if (sel_features.count(&feature)) fill = 3; gl.SetFillColour(colour[fill], 0.6f); - cur->Draw(gl); + feature.Draw(gl); } } template -void VisualTool::SetSelection(feature_iterator feat, bool clear) { +void VisualTool::SetSelection(FeatureType *feat, bool clear) { if (clear) sel_features.clear(); @@ -325,12 +317,10 @@ void VisualTool::SetSelection(feature_iterator feat, bool clear) { } template -void VisualTool::RemoveSelection(feature_iterator feat) { +void VisualTool::RemoveSelection(FeatureType *feat) { if (!sel_features.erase(feat) || !feat->line) return; - - for (auto sel : sel_features) { + for (auto sel : sel_features) if (sel->line == feat->line) return; - } SubtitleSelection sel = c->selectionController->GetSelectedSet(); diff --git a/aegisub/src/visual_tool.h b/aegisub/src/visual_tool.h index 967fcd51e..4706e5502 100644 --- a/aegisub/src/visual_tool.h +++ b/aegisub/src/visual_tool.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011, Thomas Goyne +// Copyright (c) 2013, Thomas Goyne // // Permission to use, copy, modify, and distribute this software for any // purpose with or without fee is hereby granted, provided that the above @@ -20,22 +20,17 @@ #pragma once -#include -#include -#include -#include -#include - -#include - -#include - -#include - #include "gl_wrap.h" #include "selection_controller.h" #include "vector2d.h" +#include +#include + +#include +#include +#include + class AssDialogue; class SubtitlesGrid; class VideoDisplay; @@ -155,21 +150,9 @@ template class VisualTool : public VisualToolBase { protected: typedef FeatureType Feature; - typedef typename boost::container::list::iterator feature_iterator; - typedef typename boost::container::list::const_iterator feature_const_iterator; + typedef agi::owning_intrusive_list feature_list; private: - struct ltaddr { - template - bool operator()(T lft, T rgt) const { - return &*lft < &*rgt; - } - }; - - boost::container::list slots; - - typedef typename std::set::iterator selection_iterator; - bool sel_changed; /// Has the selection already been changed in the current click? /// @brief Called when a hold is begun @@ -181,23 +164,22 @@ private: /// @brief Called at the beginning of a drag /// @param feature The visual feature clicked on /// @return Should the drag happen? - virtual bool InitializeDrag(feature_iterator feature) { return true; } + virtual bool InitializeDrag(FeatureType *feature) { return true; } /// @brief Called on every mouse event during a drag /// @param feature The current feature to process; not necessarily the one clicked on - virtual void UpdateDrag(feature_iterator feature) { } + virtual void UpdateDrag(FeatureType *feature) { } /// @brief Draw stuff virtual void Draw()=0; protected: - std::set sel_features; ///< Currently selected visual features - typedef typename std::set::const_iterator sel_iterator; + std::set sel_features; ///< Currently selected visual features /// Topmost feature under the mouse; generally only valid during a drag - feature_iterator active_feature; + FeatureType *active_feature; /// List of features which are drawn and can be clicked on /// List is used here for the iterator invalidation properties - boost::container::list features; + feature_list features; /// Draw all of the features in the list void DrawAllFeatures(); @@ -205,11 +187,11 @@ protected: /// @brief Remove a feature from the selection /// @param i Index in the feature list /// Also deselects lines if all features for that line have been deselected - void RemoveSelection(feature_iterator feat); + void RemoveSelection(FeatureType *feat); /// @brief Set the selection to a single feature, deselecting everything else /// @param i Index in the feature list - void SetSelection(feature_iterator feat, bool clear); + void SetSelection(FeatureType *feat, bool clear); public: /// @brief Handler for all mouse events diff --git a/aegisub/src/visual_tool_clip.cpp b/aegisub/src/visual_tool_clip.cpp index a5dd5552b..8cef3258f 100644 --- a/aegisub/src/visual_tool_clip.cpp +++ b/aegisub/src/visual_tool_clip.cpp @@ -36,18 +36,11 @@ VisualToolClip::VisualToolClip(VideoDisplay *parent, agi::Context *context) , cur_2(video_res) , inverse(false) { - Feature feat; - feat.type = DRAG_SMALL_CIRCLE; - features.resize(4, feat); - - // This is really awkward without being able to just index the list of - // features, so copy them into a temporary array ClipCorner *feats[4]; - feature_iterator cur = features.begin(); - feats[0] = &*(cur++); - feats[1] = &*(cur++); - feats[2] = &*(cur++); - feats[3] = &*(cur++); + for (size_t i = 0; i < 4; ++i) { + feats[i] = new ClipCorner; + features.push_back(*feats[i]); + } // Attach each feature to the two features it shares edges with // Top-left @@ -123,11 +116,7 @@ void VisualToolClip::CommitHold() { } } -bool VisualToolClip::InitializeDrag(feature_iterator) { - return true; -} - -void VisualToolClip::UpdateDrag(feature_iterator feature) { +void VisualToolClip::UpdateDrag(ClipCorner *feature) { // Update features which share an edge with the dragged one feature->horiz->pos = Vector2D(feature->horiz->pos, feature->pos); feature->vert->pos = Vector2D(feature->pos, feature->vert->pos); @@ -139,7 +128,7 @@ void VisualToolClip::UpdateDrag(feature_iterator feature) { } void VisualToolClip::SetFeaturePositions() { - feature_iterator it = features.begin(); + auto it = features.begin(); (it++)->pos = cur_1; // Top-left (it++)->pos = Vector2D(cur_2, cur_1); // Top-right (it++)->pos = Vector2D(cur_1, cur_2); // Bottom-left diff --git a/aegisub/src/visual_tool_clip.h b/aegisub/src/visual_tool_clip.h index 4da67e35c..96f744a90 100644 --- a/aegisub/src/visual_tool_clip.h +++ b/aegisub/src/visual_tool_clip.h @@ -26,7 +26,7 @@ struct ClipCorner : public VisualDraggableFeature { ClipCorner *horiz; ///< Other corner on this corner's horizontal line ClipCorner *vert; ///< Other corner on this corner's vertical line - ClipCorner() : VisualDraggableFeature() , horiz(0) , vert(0) { } + ClipCorner() : VisualDraggableFeature() , horiz(0) , vert(0) { type = DRAG_SMALL_CIRCLE; } }; class VisualToolClip : public VisualTool { @@ -42,8 +42,8 @@ class VisualToolClip : public VisualTool { void DoRefresh(); void SetFeaturePositions(); - bool InitializeDrag(feature_iterator feature); - void UpdateDrag(feature_iterator feature); + bool InitializeDrag(ClipCorner *feature) { return true; } + void UpdateDrag(ClipCorner *feature); void Draw(); public: diff --git a/aegisub/src/visual_tool_drag.cpp b/aegisub/src/visual_tool_drag.cpp index 9b2378f2d..a8b97e84a 100644 --- a/aegisub/src/visual_tool_drag.cpp +++ b/aegisub/src/visual_tool_drag.cpp @@ -32,6 +32,7 @@ #include "video_display.h" #include +#include #include #include @@ -47,7 +48,7 @@ static const DraggableFeatureType DRAG_END = DRAG_BIG_CIRCLE; VisualToolDrag::VisualToolDrag(VideoDisplay *parent, agi::Context *context) : VisualTool(parent, context) -, primary(0) +, primary(nullptr) , button_is_move(true) { c->selectionController->GetSelectedSet(selection); @@ -112,7 +113,7 @@ void VisualToolDrag::OnFileChanged() { features.clear(); sel_features.clear(); primary = 0; - active_feature = features.end(); + active_feature = nullptr; for (auto diag : c->ass->Line | agi::of_type()) { if (IsDisplayed(diag)) @@ -126,8 +127,8 @@ void VisualToolDrag::OnFrameChanged() { if (primary && !IsDisplayed(primary->line)) primary = 0; - feature_iterator feat = features.begin(); - feature_iterator end = features.end(); + auto feat = features.begin(); + auto end = features.end(); for (auto diag : c->ass->Line | agi::of_type()) { if (IsDisplayed(diag)) { @@ -141,9 +142,9 @@ void VisualToolDrag::OnFrameChanged() { else { // Remove all features for this line (if any) while (feat != end && feat->line == diag) { - if (feat == active_feature) active_feature = features.end(); - feat->line = 0; - RemoveSelection(feat); + if (&*feat == active_feature) active_feature = nullptr; + feat->line = nullptr; + RemoveSelection(&*feat); feat = features.erase(feat); } } @@ -151,21 +152,23 @@ void VisualToolDrag::OnFrameChanged() { } template static bool line_not_present(C const& set, T const& it) { - return std::none_of(set.begin(), set.end(), [&](T const& cmp) { return cmp->line == it->line; }); + return std::none_of(set.begin(), set.end(), [&](typename C::value_type const& cmp) { + return cmp->line == it->line; + }); } void VisualToolDrag::OnSelectedSetChanged(const SubtitleSelection &added, const SubtitleSelection &removed) { c->selectionController->GetSelectedSet(selection); bool any_changed = false; - for (feature_iterator it = features.begin(); it != features.end(); ) { + for (auto it = features.begin(); it != features.end(); ) { if (removed.count(it->line)) { - sel_features.erase(it++); + sel_features.erase(&*it++); any_changed = true; } else { if (added.count(it->line) && it->type == DRAG_START && line_not_present(sel_features, it)) { - sel_features.insert(it); + sel_features.insert(&*it); any_changed = true; } ++it; @@ -180,11 +183,11 @@ void VisualToolDrag::Draw() { DrawAllFeatures(); // Draw connecting lines - for (feature_iterator cur = features.begin(); cur != features.end(); ++cur) { - if (cur->type == DRAG_START) continue; + for (auto& feature : features) { + if (feature.type == DRAG_START) continue; - feature_iterator p2 = cur; - feature_iterator p1 = cur->parent; + Feature *p2 = &feature; + Feature *p1 = feature.parent; // Move end marker has an arrow; origin doesn't bool has_arrow = p2->type == DRAG_END; @@ -221,51 +224,54 @@ void VisualToolDrag::MakeFeatures(AssDialogue *diag) { MakeFeatures(diag, features.end()); } -void VisualToolDrag::MakeFeatures(AssDialogue *diag, feature_iterator pos) { +void VisualToolDrag::MakeFeatures(AssDialogue *diag, feature_list::iterator pos) { Vector2D p1 = FromScriptCoords(GetLinePosition(diag)); // Create \pos feature - Feature feat; - feat.pos = p1; - feat.layer = 0; - feat.type = DRAG_START; - feat.time = 0; - feat.line = diag; - feat.parent = features.end(); - features.insert(pos, feat); - feature_iterator cur = prev(pos); - feat.parent = cur; + auto feat = agi::util::make_unique(); + auto parent = feat.get(); + feat->pos = p1; + feat->type = DRAG_START; + feat->line = diag; + if (selection.count(diag)) - sel_features.insert(cur); + sel_features.insert(feat.get()); + features.insert(pos, *feat.release()); Vector2D p2; int t1, t2; // Create move destination feature if (GetLineMove(diag, p1, p2, t1, t2)) { - feat.pos = FromScriptCoords(p2); - feat.layer = 1; - feat.type = DRAG_END; - feat.parent->time = t1; - feat.time = t2; - feat.line = diag; - features.insert(pos, feat); - feat.parent->parent = prev(pos); + feat = agi::util::make_unique(); + feat->pos = FromScriptCoords(p2); + feat->layer = 1; + feat->type = DRAG_END; + feat->time = t2; + feat->line = diag; + feat->parent = parent; + + parent->time = t1; + parent->parent = feat.get(); + + features.insert(pos, *feat.release()); } // Create org feature if (Vector2D org = GetLineOrigin(diag)) { - feat.pos = FromScriptCoords(org); - feat.layer = -1; - feat.type = DRAG_ORIGIN; - feat.time = 0; - feat.line = diag; - features.insert(pos, feat); + feat = agi::util::make_unique(); + feat->pos = FromScriptCoords(org); + feat->layer = -1; + feat->type = DRAG_ORIGIN; + feat->time = 0; + feat->line = diag; + feat->parent = parent; + features.insert(pos, *feat.release()); } } -bool VisualToolDrag::InitializeDrag(feature_iterator feature) { - primary = &*feature; +bool VisualToolDrag::InitializeDrag(Feature *feature) { + primary = feature; // Set time of clicked feature to the current frame and shift all other // selected features by the same amount @@ -279,17 +285,17 @@ bool VisualToolDrag::InitializeDrag(feature_iterator feature) { return true; } -void VisualToolDrag::UpdateDrag(feature_iterator feature) { +void VisualToolDrag::UpdateDrag(Feature *feature) { if (feature->type == DRAG_ORIGIN) { SetOverride(feature->line, "\\org", ToScriptCoords(feature->pos).PStr()); return; } - feature_iterator end_feature = feature->parent; + Feature *end_feature = feature->parent; if (feature->type == DRAG_END) std::swap(feature, end_feature); - if (feature->parent == features.end()) + if (!feature->parent) SetOverride(feature->line, "\\pos", ToScriptCoords(feature->pos).PStr()); else SetOverride(feature->line, "\\move", diff --git a/aegisub/src/visual_tool_drag.h b/aegisub/src/visual_tool_drag.h index 6fc4d410a..464540f2c 100644 --- a/aegisub/src/visual_tool_drag.h +++ b/aegisub/src/visual_tool_drag.h @@ -27,8 +27,8 @@ class VisualToolDragDraggableFeature : public VisualDraggableFeature { public: int time; - boost::container::list::iterator parent; - VisualToolDragDraggableFeature() : VisualDraggableFeature(), time(0) { } + VisualToolDragDraggableFeature *parent; + VisualToolDragDraggableFeature() : VisualDraggableFeature(), time(0), parent(nullptr) { } }; class wxBitmapButton; @@ -54,7 +54,7 @@ class VisualToolDrag : public VisualTool { /// @brief Create the features for a line /// @param diag Line to create the features for /// @param pos Insertion point in the feature list - void MakeFeatures(AssDialogue *diag, feature_iterator pos); + void MakeFeatures(AssDialogue *diag, feature_list::iterator pos); void MakeFeatures(AssDialogue *diag); void OnSelectedSetChanged(SubtitleSelection const& lines_added, SubtitleSelection const& lines_removed); @@ -64,8 +64,8 @@ class VisualToolDrag : public VisualTool { void OnLineChanged(); void OnCoordinateSystemsChanged() { OnFileChanged(); } - bool InitializeDrag(feature_iterator feature); - void UpdateDrag(feature_iterator feature); + bool InitializeDrag(Feature *feature); + void UpdateDrag(Feature *feature); void Draw(); void OnDoubleClick(); diff --git a/aegisub/src/visual_tool_rotatexy.cpp b/aegisub/src/visual_tool_rotatexy.cpp index 353d4a6e6..294dbf9bb 100644 --- a/aegisub/src/visual_tool_rotatexy.cpp +++ b/aegisub/src/visual_tool_rotatexy.cpp @@ -33,9 +33,9 @@ VisualToolRotateXY::VisualToolRotateXY(VideoDisplay *parent, agi::Context *conte , orig_x(0) , orig_y(0) { - features.resize(1); - org = &features.back(); + org = new Feature; org->type = DRAG_BIG_TRIANGLE; + features.push_back(*org); } void VisualToolRotateXY::Draw() { @@ -161,7 +161,7 @@ void VisualToolRotateXY::UpdateHold() { SetSelectedOverride("\\fry", str(boost::format("%.4g") % angle_y)); } -void VisualToolRotateXY::UpdateDrag(feature_iterator feature) { +void VisualToolRotateXY::UpdateDrag(Feature *feature) { SetOverride(active_line, "\\org", ToScriptCoords(feature->pos).PStr()); } diff --git a/aegisub/src/visual_tool_rotatexy.h b/aegisub/src/visual_tool_rotatexy.h index 64c8d8d98..7b2a12c5c 100644 --- a/aegisub/src/visual_tool_rotatexy.h +++ b/aegisub/src/visual_tool_rotatexy.h @@ -34,7 +34,7 @@ class VisualToolRotateXY : public VisualTool { void DoRefresh(); void Draw(); - void UpdateDrag(feature_iterator feature); + void UpdateDrag(Feature *feature); bool InitializeHold(); void UpdateHold(); public: diff --git a/aegisub/src/visual_tool_rotatez.cpp b/aegisub/src/visual_tool_rotatez.cpp index 8ff490953..ae83a948a 100644 --- a/aegisub/src/visual_tool_rotatez.cpp +++ b/aegisub/src/visual_tool_rotatez.cpp @@ -36,9 +36,9 @@ VisualToolRotateZ::VisualToolRotateZ(VideoDisplay *parent, agi::Context *context , orig_angle(0) , rotation_x(0) , rotation_y(0) +, org(new Feature) { - features.resize(1); - org = &features.back(); + features.push_back(*org); org->type = DRAG_BIG_TRIANGLE; } @@ -118,7 +118,7 @@ void VisualToolRotateZ::UpdateHold() { SetSelectedOverride("\\frz", str(boost::format("%.4g") % angle)); } -void VisualToolRotateZ::UpdateDrag(feature_iterator feature) { +void VisualToolRotateZ::UpdateDrag(Feature *feature) { SetOverride(active_line, "\\org", ToScriptCoords(feature->pos).PStr()); } diff --git a/aegisub/src/visual_tool_rotatez.h b/aegisub/src/visual_tool_rotatez.h index 9cdb627ba..753148333 100644 --- a/aegisub/src/visual_tool_rotatez.h +++ b/aegisub/src/visual_tool_rotatez.h @@ -36,7 +36,7 @@ class VisualToolRotateZ : public VisualTool { bool InitializeHold(); void UpdateHold(); - void UpdateDrag(feature_iterator feature); + void UpdateDrag(Feature *feature); void DoRefresh(); diff --git a/aegisub/src/visual_tool_vector_clip.cpp b/aegisub/src/visual_tool_vector_clip.cpp index 600f337a9..f06878f37 100644 --- a/aegisub/src/visual_tool_vector_clip.cpp +++ b/aegisub/src/visual_tool_vector_clip.cpp @@ -29,6 +29,8 @@ #include "selection_controller.h" #include "utils.h" +#include + #include #include @@ -111,7 +113,7 @@ void VisualToolVectorClip::Draw() { spline.GetClosestParametricPoint(mouse_pos, highlighted_curve, t, pt); // Draw highlighted line - if ((mode == 3 || mode == 4) && active_feature == features.end() && points.size() > 2) { + if ((mode == 3 || mode == 4) && !active_feature && points.size() > 2) { std::vector highlighted_points; spline.GetPointList(highlighted_points, highlighted_curve); if (!highlighted_points.empty()) { @@ -148,42 +150,47 @@ void VisualToolVectorClip::Draw() { } void VisualToolVectorClip::MakeFeature(Spline::iterator cur) { - Feature feat; - feat.curve = cur; + auto feat = agi::util::make_unique(); + feat->curve = cur; if (cur->type == SplineCurve::POINT) { - feat.pos = cur->p1; - feat.type = DRAG_SMALL_CIRCLE; - feat.point = 0; + feat->pos = cur->p1; + feat->type = DRAG_SMALL_CIRCLE; + feat->point = 0; } else if (cur->type == SplineCurve::LINE) { - feat.pos = cur->p2; - feat.type = DRAG_SMALL_CIRCLE; - feat.point = 1; + feat->pos = cur->p2; + feat->type = DRAG_SMALL_CIRCLE; + feat->point = 1; } else if (cur->type == SplineCurve::BICUBIC) { // Control points - feat.pos = cur->p2; - feat.point = 1; - feat.type = DRAG_SMALL_SQUARE; - features.push_back(feat); + feat->pos = cur->p2; + feat->point = 1; + feat->type = DRAG_SMALL_SQUARE; + features.push_back(*feat.release()); - feat.pos = cur->p3; - feat.point = 2; - features.push_back(feat); + feat = agi::util::make_unique(); + feat->curve = cur; + feat->pos = cur->p3; + feat->point = 2; + feat->type = DRAG_SMALL_SQUARE; + features.push_back(*feat.release()); // End point - feat.pos = cur->p4; - feat.type = DRAG_SMALL_CIRCLE; - feat.point = 3; + feat = agi::util::make_unique(); + feat->curve = cur; + feat->pos = cur->p4; + feat->point = 3; + feat->type = DRAG_SMALL_CIRCLE; } - features.push_back(feat); + features.push_back(*feat.release()); } void VisualToolVectorClip::MakeFeatures() { sel_features.clear(); features.clear(); - active_feature = features.end(); + active_feature = nullptr; for (auto it = spline.begin(); it != spline.end(); ++it) MakeFeature(it); } @@ -202,12 +209,12 @@ void VisualToolVectorClip::Save() { } } -void VisualToolVectorClip::UpdateDrag(feature_iterator feature) { +void VisualToolVectorClip::UpdateDrag(Feature *feature) { spline.MovePoint(feature->curve, feature->point, feature->pos); Save(); } -bool VisualToolVectorClip::InitializeDrag(feature_iterator feature) { +bool VisualToolVectorClip::InitializeDrag(Feature *feature) { if (mode != 5) return true; if (feature->curve->type == SplineCurve::BICUBIC && (feature->point == 1 || feature->point == 2)) { @@ -229,7 +236,7 @@ bool VisualToolVectorClip::InitializeDrag(feature_iterator feature) { spline.erase(feature->curve); } - active_feature = features.end(); + active_feature = nullptr; Save(); MakeFeatures(); @@ -313,16 +320,15 @@ bool VisualToolVectorClip::InitializeHold() { if (mode == 6 || mode == 7) { sel_features.clear(); features.clear(); - active_feature = features.end(); + active_feature = nullptr; spline.clear(); spline.emplace_back(mouse_pos); return true; } /// @todo box selection? - if (mode == 0) { + if (mode == 0) return false; - } // Nothing to do for mode 5 (remove) return false; @@ -398,6 +404,6 @@ void VisualToolVectorClip::DoRefresh() { void VisualToolVectorClip::SelectAll() { sel_features.clear(); - for (feature_iterator it = features.begin(); it != features.end(); ++it) - sel_features.insert(it); + for (auto& feature : features) + sel_features.insert(&feature); } diff --git a/aegisub/src/visual_tool_vector_clip.h b/aegisub/src/visual_tool_vector_clip.h index b3c232d06..ceaa72ae1 100644 --- a/aegisub/src/visual_tool_vector_clip.h +++ b/aegisub/src/visual_tool_vector_clip.h @@ -35,8 +35,8 @@ struct VisualToolVectorClipDraggableFeature : public VisualDraggableFeature { int point; /// @brief Constructor VisualToolVectorClipDraggableFeature() - : VisualDraggableFeature() - , point(0) + : VisualDraggableFeature() + , point(0) { } }; @@ -59,8 +59,8 @@ class VisualToolVectorClip : public VisualTool