Make visual tools pass around iterators for everything related to visual features rather than a mix of pointers and indices, and clean up feature creation. Fixes a large pile of selection-related bugs.
Originally committed to SVN as r4648.
This commit is contained in:
parent
8bd5b16699
commit
be1ed9e672
14 changed files with 373 additions and 379 deletions
|
@ -47,7 +47,6 @@ VisualDraggableFeature::VisualDraggableFeature()
|
||||||
, origY(INT_MIN)
|
, origY(INT_MIN)
|
||||||
, layer(0)
|
, layer(0)
|
||||||
, line(NULL)
|
, line(NULL)
|
||||||
, lineN(-1)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,6 @@ public:
|
||||||
int layer; /// Layer; Higher = above
|
int layer; /// Layer; Higher = above
|
||||||
|
|
||||||
AssDialogue* line; /// The dialogue line this feature is for
|
AssDialogue* line; /// The dialogue line this feature is for
|
||||||
int lineN; /// The line's index in the file
|
|
||||||
|
|
||||||
/// @brief Is the given point over this feature?
|
/// @brief Is the given point over this feature?
|
||||||
/// @param mx x coordinate to test
|
/// @param mx x coordinate to test
|
||||||
|
|
|
@ -75,13 +75,12 @@ VisualTool<FeatureType>::VisualTool(VideoDisplay *parent, VideoState const& vide
|
||||||
, dragStartX(0)
|
, dragStartX(0)
|
||||||
, dragStartY(0)
|
, dragStartY(0)
|
||||||
, selChanged(false)
|
, selChanged(false)
|
||||||
|
, selectedFeatures(selFeatures)
|
||||||
, grid(VideoContext::Get()->grid)
|
, grid(VideoContext::Get()->grid)
|
||||||
, parent(parent)
|
, parent(parent)
|
||||||
, holding(false)
|
, holding(false)
|
||||||
, dragging(false)
|
, dragging(false)
|
||||||
, externalChange(true)
|
, externalChange(true)
|
||||||
, curFeature(NULL)
|
|
||||||
, dragListOK(false)
|
|
||||||
, video(video)
|
, video(video)
|
||||||
, leftClick(false)
|
, leftClick(false)
|
||||||
, leftDClick(false)
|
, leftDClick(false)
|
||||||
|
@ -92,6 +91,7 @@ VisualTool<FeatureType>::VisualTool(VideoDisplay *parent, VideoState const& vide
|
||||||
frameNumber = VideoContext::Get()->GetFrameN();
|
frameNumber = VideoContext::Get()->GetFrameN();
|
||||||
curDiag = GetActiveDialogueLine();
|
curDiag = GetActiveDialogueLine();
|
||||||
grid->AddSelectionListener(this);
|
grid->AddSelectionListener(this);
|
||||||
|
curFeature = features.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class FeatureType>
|
template<class FeatureType>
|
||||||
|
@ -124,35 +124,30 @@ void VisualTool<FeatureType>::OnMouseEvent(wxMouseEvent &event) {
|
||||||
#endif
|
#endif
|
||||||
altDown = event.m_altDown;
|
altDown = event.m_altDown;
|
||||||
|
|
||||||
if (!dragListOK) {
|
|
||||||
PopulateFeatureList();
|
|
||||||
dragListOK = true;
|
|
||||||
needRender = true;
|
|
||||||
}
|
|
||||||
if (!dragging) {
|
if (!dragging) {
|
||||||
unsigned oldHigh = curFeatureI;
|
feature_iterator oldHigh = curFeature;
|
||||||
GetHighlightedFeature();
|
GetHighlightedFeature();
|
||||||
if (curFeatureI != oldHigh) needRender = true;
|
if (curFeature != oldHigh) needRender = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dragging) {
|
if (dragging) {
|
||||||
// continue drag
|
// continue drag
|
||||||
if (event.LeftIsDown()) {
|
if (event.LeftIsDown()) {
|
||||||
for (selection_iterator cur = selFeatures.begin(); cur != selFeatures.end(); ++cur) {
|
for (selection_iterator cur = selFeatures.begin(); cur != selFeatures.end(); ++cur) {
|
||||||
features[*cur].x = (video.x - dragStartX + features[*cur].origX);
|
(*cur)->x = (video.x - dragStartX + (*cur)->origX);
|
||||||
features[*cur].y = (video.y - dragStartY + features[*cur].origY);
|
(*cur)->y = (video.y - dragStartY + (*cur)->origY);
|
||||||
if (shiftDown) {
|
if (shiftDown) {
|
||||||
if (abs(video.x - dragStartX) > abs(video.y - dragStartY)) {
|
if (abs(video.x - dragStartX) > abs(video.y - dragStartY)) {
|
||||||
features[*cur].y = features[*cur].origY;
|
(*cur)->y = (*cur)->origY;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
features[*cur].x = features[*cur].origX;
|
(*cur)->x = (*cur)->origX;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UpdateDrag(&features[*cur]);
|
UpdateDrag(*cur);
|
||||||
|
|
||||||
if (realTime) {
|
if (realTime) {
|
||||||
CommitDrag(&features[*cur]);
|
CommitDrag(*cur);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (realTime) {
|
if (realTime) {
|
||||||
|
@ -172,21 +167,21 @@ void VisualTool<FeatureType>::OnMouseEvent(wxMouseEvent &event) {
|
||||||
if (!selChanged) {
|
if (!selChanged) {
|
||||||
if (ctrlDown) {
|
if (ctrlDown) {
|
||||||
// deselect this feature
|
// deselect this feature
|
||||||
RemoveSelection(curFeatureI);
|
RemoveSelection(curFeature);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SetSelection(curFeatureI);
|
SetSelection(curFeature);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (selection_iterator cur = selFeatures.begin(); cur != selFeatures.end(); ++cur) {
|
for (selection_iterator cur = selFeatures.begin(); cur != selFeatures.end(); ++cur) {
|
||||||
CommitDrag(&features[*cur]);
|
CommitDrag(*cur);
|
||||||
}
|
}
|
||||||
Commit(true);
|
Commit(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
curFeature = NULL;
|
curFeature = features.end();
|
||||||
parent->ReleaseMouse();
|
parent->ReleaseMouse();
|
||||||
parent->SetFocus();
|
parent->SetFocus();
|
||||||
}
|
}
|
||||||
|
@ -216,27 +211,27 @@ void VisualTool<FeatureType>::OnMouseEvent(wxMouseEvent &event) {
|
||||||
}
|
}
|
||||||
else if (leftClick) {
|
else if (leftClick) {
|
||||||
// start drag
|
// start drag
|
||||||
if (curFeature) {
|
if (curFeature != features.end()) {
|
||||||
if (InitializeDrag(curFeature)) {
|
if (selFeatures.find(curFeature) == selFeatures.end()) {
|
||||||
if (selFeatures.find(curFeatureI) == selFeatures.end()) {
|
selChanged = true;
|
||||||
selChanged = true;
|
if (ctrlDown) {
|
||||||
if (ctrlDown) {
|
AddSelection(curFeature);
|
||||||
AddSelection(curFeatureI);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
SetSelection(curFeatureI);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
selChanged = false;
|
SetSelection(curFeature);
|
||||||
}
|
}
|
||||||
if (curFeature->line) grid->SetActiveLine(curFeature->line);
|
}
|
||||||
|
else {
|
||||||
|
selChanged = false;
|
||||||
|
}
|
||||||
|
if (curFeature->line) grid->SetActiveLine(curFeature->line);
|
||||||
|
|
||||||
|
if (InitializeDrag(curFeature)) {
|
||||||
dragStartX = video.x;
|
dragStartX = video.x;
|
||||||
dragStartY = video.y;
|
dragStartY = video.y;
|
||||||
for (selection_iterator cur = selFeatures.begin(); cur != selFeatures.end(); ++cur) {
|
for (selection_iterator cur = selFeatures.begin(); cur != selFeatures.end(); ++cur) {
|
||||||
features[*cur].origX = features[*cur].x;
|
(*cur)->origX = (*cur)->x;
|
||||||
features[*cur].origY = features[*cur].y;
|
(*cur)->origY = (*cur)->y;
|
||||||
}
|
}
|
||||||
|
|
||||||
dragging = true;
|
dragging = true;
|
||||||
|
@ -291,13 +286,10 @@ AssDialogue* VisualTool<FeatureType>::GetActiveDialogueLine() {
|
||||||
template<class FeatureType>
|
template<class FeatureType>
|
||||||
void VisualTool<FeatureType>::GetHighlightedFeature() {
|
void VisualTool<FeatureType>::GetHighlightedFeature() {
|
||||||
int highestLayerFound = INT_MIN;
|
int highestLayerFound = INT_MIN;
|
||||||
curFeature = NULL;
|
curFeature = features.end();
|
||||||
curFeatureI = -1;
|
for (feature_iterator cur = features.begin(); cur != features.end(); ++cur) {
|
||||||
unsigned i = 0;
|
|
||||||
for (feature_iterator cur = features.begin(); cur != features.end(); ++cur, ++i) {
|
|
||||||
if (cur->IsMouseOver(video.x, video.y) && cur->layer > highestLayerFound) {
|
if (cur->IsMouseOver(video.x, video.y) && cur->layer > highestLayerFound) {
|
||||||
curFeature = &*cur;
|
curFeature = cur;
|
||||||
curFeatureI = i;
|
|
||||||
highestLayerFound = cur->layer;
|
highestLayerFound = cur->layer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -305,30 +297,25 @@ void VisualTool<FeatureType>::GetHighlightedFeature() {
|
||||||
|
|
||||||
template<class FeatureType>
|
template<class FeatureType>
|
||||||
void VisualTool<FeatureType>::DrawAllFeatures() {
|
void VisualTool<FeatureType>::DrawAllFeatures() {
|
||||||
if (!dragListOK) {
|
|
||||||
PopulateFeatureList();
|
|
||||||
dragListOK = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
SetLineColour(colour[0],1.0f,2);
|
SetLineColour(colour[0],1.0f,2);
|
||||||
for (unsigned i = 0; i < features.size(); ++i) {
|
for (feature_iterator cur = features.begin(); cur != features.end(); ++cur) {
|
||||||
int fill;
|
int fill;
|
||||||
if (&features[i] == curFeature)
|
if (cur == curFeature)
|
||||||
fill = 2;
|
fill = 2;
|
||||||
else if (selFeatures.find(i) != selFeatures.end())
|
else if (selFeatures.find(cur) != selFeatures.end())
|
||||||
fill = 3;
|
fill = 3;
|
||||||
else
|
else
|
||||||
fill = 1;
|
fill = 1;
|
||||||
SetFillColour(colour[fill],0.6f);
|
SetFillColour(colour[fill],0.6f);
|
||||||
features[i].Draw(*this);
|
cur->Draw(*this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class FeatureType>
|
template<class FeatureType>
|
||||||
void VisualTool<FeatureType>::Refresh() {
|
void VisualTool<FeatureType>::Refresh() {
|
||||||
if (externalChange) {
|
if (externalChange) {
|
||||||
dragListOK = false;
|
|
||||||
curDiag = GetActiveDialogueLine();
|
curDiag = GetActiveDialogueLine();
|
||||||
|
curFeature = features.end();
|
||||||
OnFileChanged();
|
OnFileChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -336,6 +323,8 @@ void VisualTool<FeatureType>::Refresh() {
|
||||||
template<class FeatureType>
|
template<class FeatureType>
|
||||||
void VisualTool<FeatureType>::SetFrame(int newFrameNumber) {
|
void VisualTool<FeatureType>::SetFrame(int newFrameNumber) {
|
||||||
if (frameNumber == newFrameNumber) return;
|
if (frameNumber == newFrameNumber) return;
|
||||||
|
frameNumber = newFrameNumber;
|
||||||
|
curFeature = features.end();
|
||||||
OnFrameChanged();
|
OnFrameChanged();
|
||||||
AssDialogue *newCurDiag = GetActiveDialogueLine();
|
AssDialogue *newCurDiag = GetActiveDialogueLine();
|
||||||
if (newCurDiag != curDiag) {
|
if (newCurDiag != curDiag) {
|
||||||
|
@ -357,14 +346,13 @@ void VisualTool<FeatureType>::OnActiveLineChanged(AssDialogue *new_line) {
|
||||||
|
|
||||||
|
|
||||||
template<class FeatureType>
|
template<class FeatureType>
|
||||||
void VisualTool<FeatureType>::SetSelection(unsigned i) {
|
void VisualTool<FeatureType>::SetSelection(feature_iterator feat) {
|
||||||
assert(i < features.size());
|
|
||||||
|
|
||||||
selFeatures.clear();
|
selFeatures.clear();
|
||||||
lineSelCount.clear();
|
lineSelCount.clear();
|
||||||
selFeatures.insert(i);
|
|
||||||
|
|
||||||
AssDialogue *line = features[i].line;
|
selFeatures.insert(feat);
|
||||||
|
|
||||||
|
AssDialogue *line = feat->line;
|
||||||
if (line) {
|
if (line) {
|
||||||
lineSelCount[line] = 1;
|
lineSelCount[line] = 1;
|
||||||
|
|
||||||
|
@ -376,23 +364,22 @@ void VisualTool<FeatureType>::SetSelection(unsigned i) {
|
||||||
|
|
||||||
|
|
||||||
template<class FeatureType>
|
template<class FeatureType>
|
||||||
void VisualTool<FeatureType>::AddSelection(unsigned i) {
|
void VisualTool<FeatureType>::AddSelection(feature_iterator feat) {
|
||||||
assert(i < features.size());
|
if (selFeatures.insert(feat).second && feat->line) {
|
||||||
|
lineSelCount[feat->line] += 1;
|
||||||
if (selFeatures.insert(i).second && features[i].line) {
|
Selection sel = grid->GetSelectedSet();
|
||||||
lineSelCount[features[i].line] += 1;
|
if (sel.insert(feat->line).second) {
|
||||||
grid->SelectRow(features[i].lineN, true);
|
grid->SetSelectedSet(sel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<class FeatureType>
|
template<class FeatureType>
|
||||||
void VisualTool<FeatureType>::RemoveSelection(unsigned i) {
|
void VisualTool<FeatureType>::RemoveSelection(feature_iterator feat) {
|
||||||
assert(i < features.size());
|
if (selFeatures.erase(feat) > 0 && feat->line) {
|
||||||
|
|
||||||
if (selFeatures.erase(i) > 0 && features[i].line) {
|
|
||||||
// Deselect a line only if all features for that line have been
|
// Deselect a line only if all features for that line have been
|
||||||
// deselected
|
// deselected
|
||||||
AssDialogue* line = features[i].line;
|
AssDialogue* line = feat->line;
|
||||||
lineSelCount[line] -= 1;
|
lineSelCount[line] -= 1;
|
||||||
assert(lineSelCount[line] >= 0);
|
assert(lineSelCount[line] >= 0);
|
||||||
if (lineSelCount[line] <= 0) {
|
if (lineSelCount[line] <= 0) {
|
||||||
|
|
|
@ -76,28 +76,39 @@ public:
|
||||||
virtual ~IVisualTool() { };
|
virtual ~IVisualTool() { };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ltaddr {
|
||||||
|
template<class T>
|
||||||
|
bool operator()(T lft, T rgt) const {
|
||||||
|
return &*lft < &*rgt;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/// DOCME
|
/// DOCME
|
||||||
/// @class VisualTool
|
/// @class VisualTool
|
||||||
/// @brief DOCME
|
/// @brief DOCME
|
||||||
/// DOCME
|
/// DOCME
|
||||||
template<class FeatureType>
|
template<class FeatureType>
|
||||||
class VisualTool : public IVisualTool, protected SubtitleSelectionListener {
|
class VisualTool : public IVisualTool, protected SubtitleSelectionListener {
|
||||||
|
protected:
|
||||||
|
typedef typename FeatureType Feature;
|
||||||
|
typedef typename std::list<FeatureType>::iterator feature_iterator;
|
||||||
|
typedef typename std::list<FeatureType>::const_iterator feature_const_iterator;
|
||||||
private:
|
private:
|
||||||
agi::OptionValue* realtime; /// Realtime updating option
|
agi::OptionValue* realtime; /// Realtime updating option
|
||||||
int dragStartX; /// Starting x coordinate of the current drag, if any
|
int dragStartX; /// Starting x coordinate of the current drag, if any
|
||||||
int dragStartY; /// Starting y coordinate of the current drag, if any
|
int dragStartY; /// Starting y coordinate of the current drag, if any
|
||||||
|
|
||||||
/// Set curFeature and curFeatureI to the topmost feature under the mouse,
|
/// Set curFeature to the topmost feature under the mouse, or end() if there
|
||||||
/// or NULL and -1 if there are none
|
/// are none
|
||||||
void GetHighlightedFeature();
|
void GetHighlightedFeature();
|
||||||
|
|
||||||
/// @brief Get the dialogue line currently in the edit box
|
/// @brief Get the dialogue line currently in the edit box
|
||||||
/// @return NULL if the line is not active on the current frame
|
/// @return NULL if the line is not active on the current frame
|
||||||
AssDialogue *GetActiveDialogueLine();
|
AssDialogue *GetActiveDialogueLine();
|
||||||
|
|
||||||
typedef typename std::set<int>::iterator selection_iterator;
|
typedef typename std::set<feature_iterator, ltaddr>::iterator selection_iterator;
|
||||||
|
|
||||||
std::set<int> selFeatures; /// Currently selected visual features
|
std::set<feature_iterator, ltaddr> selFeatures; /// Currently selected visual features
|
||||||
std::map<AssDialogue*, int> lineSelCount; /// Number of selected features for each line
|
std::map<AssDialogue*, int> lineSelCount; /// Number of selected features for each line
|
||||||
|
|
||||||
bool selChanged; /// Has the selection already been changed in the current click?
|
bool selChanged; /// Has the selection already been changed in the current click?
|
||||||
|
@ -110,18 +121,15 @@ private:
|
||||||
/// @brief Called at the end of a hold
|
/// @brief Called at the end of a hold
|
||||||
virtual void CommitHold() { }
|
virtual void CommitHold() { }
|
||||||
|
|
||||||
/// @brief Called when the feature list needs to be (re)generated
|
|
||||||
virtual void PopulateFeatureList() { }
|
|
||||||
|
|
||||||
/// @brief Called at the beginning of a drag
|
/// @brief Called at the beginning of a drag
|
||||||
/// @param feature The visual feature clicked on
|
/// @param feature The visual feature clicked on
|
||||||
/// @return Should the drag happen?
|
/// @return Should the drag happen?
|
||||||
virtual bool InitializeDrag(FeatureType* feature) { return true; }
|
virtual bool InitializeDrag(feature_iterator feature) { return true; }
|
||||||
/// @brief Called on every mouse event during a drag
|
/// @brief Called on every mouse event during a drag
|
||||||
/// @param feature The current feature to process; not necessarily the one clicked on
|
/// @param feature The current feature to process; not necessarily the one clicked on
|
||||||
virtual void UpdateDrag(FeatureType* feature) { }
|
virtual void UpdateDrag(feature_iterator feature) { }
|
||||||
/// @brief Called at the end of a drag
|
/// @brief Called at the end of a drag
|
||||||
virtual void CommitDrag(FeatureType* feature) { }
|
virtual void CommitDrag(feature_iterator feature) { }
|
||||||
|
|
||||||
/// Called when the file is changed by something other than a visual tool
|
/// Called when the file is changed by something other than a visual tool
|
||||||
virtual void OnFileChanged() { DoRefresh(); }
|
virtual void OnFileChanged() { DoRefresh(); }
|
||||||
|
@ -141,6 +149,9 @@ private:
|
||||||
virtual void Draw()=0;
|
virtual void Draw()=0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
/// Read-only reference to the set of selected features for subclasses
|
||||||
|
const std::set<feature_iterator, ltaddr> &selectedFeatures;
|
||||||
|
typedef typename std::set<feature_iterator, ltaddr>::const_iterator sel_iterator;
|
||||||
SubtitlesGrid *grid;
|
SubtitlesGrid *grid;
|
||||||
VideoDisplay *parent; /// VideoDisplay which this belongs to, used to frame conversion
|
VideoDisplay *parent; /// VideoDisplay which this belongs to, used to frame conversion
|
||||||
bool holding; /// Is a hold currently in progress?
|
bool holding; /// Is a hold currently in progress?
|
||||||
|
@ -148,10 +159,8 @@ protected:
|
||||||
bool dragging; /// Is a drag currently in progress?
|
bool dragging; /// Is a drag currently in progress?
|
||||||
bool externalChange; /// Only invalid drag lists when refreshing due to external changes
|
bool externalChange; /// Only invalid drag lists when refreshing due to external changes
|
||||||
|
|
||||||
FeatureType* curFeature; /// Topmost feature under the mouse; generally only valid during a drag
|
feature_iterator curFeature; /// Topmost feature under the mouse; generally only valid during a drag
|
||||||
unsigned curFeatureI; /// Index of the current feature in the list
|
std::list<FeatureType> features; /// List of features which are drawn and can be clicked on
|
||||||
std::vector<FeatureType> features; /// List of features which are drawn and can be clicked on
|
|
||||||
bool dragListOK; /// Do the features not need to be regenerated?
|
|
||||||
|
|
||||||
int frameNumber; /// Current frame number
|
int frameNumber; /// Current frame number
|
||||||
VideoState const& video; /// Mouse and video information
|
VideoState const& video; /// Mouse and video information
|
||||||
|
@ -179,24 +188,20 @@ protected:
|
||||||
|
|
||||||
/// @brief Add a feature (and its line) to the selection
|
/// @brief Add a feature (and its line) to the selection
|
||||||
/// @param i Index in the feature list
|
/// @param i Index in the feature list
|
||||||
void AddSelection(unsigned i);
|
void AddSelection(feature_iterator feat);
|
||||||
|
|
||||||
/// @brief Remove a feature from the selection
|
/// @brief Remove a feature from the selection
|
||||||
/// @param i Index in the feature list
|
/// @param i Index in the feature list
|
||||||
/// Also deselects lines if all features for that line have been deselected
|
/// Also deselects lines if all features for that line have been deselected
|
||||||
void RemoveSelection(unsigned i);
|
void RemoveSelection(feature_iterator feat);
|
||||||
|
|
||||||
/// @brief Set the selection to a single feature, deselecting everything else
|
/// @brief Set the selection to a single feature, deselecting everything else
|
||||||
/// @param i Index in the feature list
|
/// @param i Index in the feature list
|
||||||
void SetSelection(unsigned i);
|
void SetSelection(feature_iterator feat);
|
||||||
|
|
||||||
/// @brief Clear the selection
|
/// @brief Clear the selection
|
||||||
void ClearSelection();
|
void ClearSelection();
|
||||||
|
|
||||||
typedef typename std::vector<FeatureType>::iterator feature_iterator;
|
|
||||||
typedef typename std::vector<FeatureType>::const_iterator feature_const_iterator;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// SubtitleSelectionListener implementation
|
// SubtitleSelectionListener implementation
|
||||||
void OnActiveLineChanged(AssDialogue *new_line);
|
void OnActiveLineChanged(AssDialogue *new_line);
|
||||||
virtual void OnSelectedSetChanged(const Selection &lines_added, const Selection &lines_removed) { }
|
virtual void OnSelectedSetChanged(const Selection &lines_added, const Selection &lines_removed) { }
|
||||||
|
|
|
@ -58,6 +58,38 @@ VisualToolClip::VisualToolClip(VideoDisplay *parent, VideoState const& video, wx
|
||||||
if (curDiag) {
|
if (curDiag) {
|
||||||
GetLineClip(curDiag,curX1,curY1,curX2,curY2,inverse);
|
GetLineClip(curDiag,curX1,curY1,curX2,curY2,inverse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Feature feat;
|
||||||
|
feat.type = DRAG_SMALL_CIRCLE;
|
||||||
|
features.resize(4, feat);
|
||||||
|
|
||||||
|
feature_iterator cur = features.begin();
|
||||||
|
feats[0] = &*(cur++);
|
||||||
|
feats[1] = &*(cur++);
|
||||||
|
feats[2] = &*(cur++);
|
||||||
|
feats[3] = &*(cur++);
|
||||||
|
|
||||||
|
|
||||||
|
// Top-left
|
||||||
|
int i = 0;
|
||||||
|
feats[i]->horiz = feats[1];
|
||||||
|
feats[i]->vert = feats[2];
|
||||||
|
i++;
|
||||||
|
|
||||||
|
// Top-right
|
||||||
|
feats[i]->horiz = feats[0];
|
||||||
|
feats[i]->vert = feats[3];
|
||||||
|
i++;
|
||||||
|
|
||||||
|
// Bottom-left
|
||||||
|
feats[i]->horiz = feats[3];
|
||||||
|
feats[i]->vert = feats[0];
|
||||||
|
i++;
|
||||||
|
|
||||||
|
// Bottom-right
|
||||||
|
feats[i]->horiz = feats[2];
|
||||||
|
feats[i]->vert = feats[1];
|
||||||
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolClip::Draw() {
|
void VisualToolClip::Draw() {
|
||||||
|
@ -101,7 +133,6 @@ bool VisualToolClip::InitializeHold() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolClip::UpdateHold() {
|
void VisualToolClip::UpdateHold() {
|
||||||
// Coordinates
|
|
||||||
curX1 = startX;
|
curX1 = startX;
|
||||||
curY1 = startY;
|
curY1 = startY;
|
||||||
curX2 = video.x;
|
curX2 = video.x;
|
||||||
|
@ -117,7 +148,7 @@ void VisualToolClip::UpdateHold() {
|
||||||
curY1 = MID(0,curY1,video.h);
|
curY1 = MID(0,curY1,video.h);
|
||||||
curY2 = MID(0,curY2,video.h);
|
curY2 = MID(0,curY2,video.h);
|
||||||
|
|
||||||
PopulateFeatureList();
|
SetFeaturePositions();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolClip::CommitHold() {
|
void VisualToolClip::CommitHold() {
|
||||||
|
@ -130,83 +161,57 @@ void VisualToolClip::CommitHold() {
|
||||||
SetOverride(curDiag, inverse ? L"\\iclip" : L"\\clip",wxString::Format(L"(%i,%i,%i,%i)",x1,y1,x2,y2));
|
SetOverride(curDiag, inverse ? L"\\iclip" : L"\\clip",wxString::Format(L"(%i,%i,%i,%i)",x1,y1,x2,y2));
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolClip::PopulateFeatureList() {
|
bool VisualToolClip::InitializeDrag(feature_iterator) {
|
||||||
if (features.size() != 4) {
|
|
||||||
ClearSelection();
|
|
||||||
features.clear();
|
|
||||||
features.resize(4);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Top-left
|
|
||||||
int i = 0;
|
|
||||||
features[i].x = curX1;
|
|
||||||
features[i].y = curY1;
|
|
||||||
features[i].horiz = &features[1];
|
|
||||||
features[i].vert = &features[2];
|
|
||||||
features[i].type = DRAG_SMALL_CIRCLE;
|
|
||||||
i++;
|
|
||||||
|
|
||||||
// Top-right
|
|
||||||
features[i].x = curX2;
|
|
||||||
features[i].y = curY1;
|
|
||||||
features[i].horiz = &features[0];
|
|
||||||
features[i].vert = &features[3];
|
|
||||||
features[i].type = DRAG_SMALL_CIRCLE;
|
|
||||||
i++;
|
|
||||||
|
|
||||||
// Bottom-left
|
|
||||||
features[i].x = curX1;
|
|
||||||
features[i].y = curY2;
|
|
||||||
features[i].horiz = &features[3];
|
|
||||||
features[i].vert = &features[0];
|
|
||||||
features[i].type = DRAG_SMALL_CIRCLE;
|
|
||||||
i++;
|
|
||||||
|
|
||||||
// Bottom-right
|
|
||||||
features[i].x = curX2;
|
|
||||||
features[i].y = curY2;
|
|
||||||
features[i].horiz = &features[2];
|
|
||||||
features[i].vert = &features[1];
|
|
||||||
features[i].type = DRAG_SMALL_CIRCLE;
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool VisualToolClip::InitializeDrag(ClipCorner*) {
|
|
||||||
curDiag->StripTag(L"\\clip");
|
curDiag->StripTag(L"\\clip");
|
||||||
curDiag->StripTag(L"\\iclip");
|
curDiag->StripTag(L"\\iclip");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolClip::UpdateDrag(ClipCorner* feature) {
|
void VisualToolClip::UpdateDrag(feature_iterator feature) {
|
||||||
// Update brothers
|
// Update brothers
|
||||||
feature->horiz->y = feature->y;
|
feature->horiz->y = feature->y;
|
||||||
feature->vert->x = feature->x;
|
feature->vert->x = feature->x;
|
||||||
|
|
||||||
// Get "cur" from features
|
// Get "cur" from features
|
||||||
curX1 = features[0].x;
|
curX1 = feats[0]->x;
|
||||||
curX2 = features[3].x;
|
curX2 = feats[3]->x;
|
||||||
curY1 = features[0].y;
|
curY1 = feats[0]->y;
|
||||||
curY2 = features[3].y;
|
curY2 = feats[3]->y;
|
||||||
|
|
||||||
// Make sure p1 < p2
|
// Make sure p1 < p2
|
||||||
if (curX1 > curX2) std::swap(curX1,curX2);
|
if (curX1 > curX2) std::swap(curX1,curX2);
|
||||||
if (curY1 > curY2) std::swap(curY1,curY2);
|
if (curY1 > curY2) std::swap(curY1,curY2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolClip::CommitDrag(ClipCorner*) {
|
void VisualToolClip::CommitDrag(feature_iterator) {
|
||||||
CommitHold();
|
CommitHold();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolClip::OnLineChanged() {
|
void VisualToolClip::SetFeaturePositions() {
|
||||||
if (curDiag) {
|
// Top-left
|
||||||
GetLineClip(curDiag,curX1,curY1,curX2,curY2,inverse);
|
int i = 0;
|
||||||
PopulateFeatureList();
|
feats[i]->x = curX1;
|
||||||
}
|
feats[i]->y = curY1;
|
||||||
|
i++;
|
||||||
|
|
||||||
|
// Top-right
|
||||||
|
feats[i]->x = curX2;
|
||||||
|
feats[i]->y = curY1;
|
||||||
|
i++;
|
||||||
|
|
||||||
|
// Bottom-left
|
||||||
|
feats[i]->x = curX1;
|
||||||
|
feats[i]->y = curY2;
|
||||||
|
i++;
|
||||||
|
|
||||||
|
// Bottom-right
|
||||||
|
feats[i]->x = curX2;
|
||||||
|
feats[i]->y = curY2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolClip::OnFileChanged() {
|
void VisualToolClip::DoRefresh() {
|
||||||
if (curDiag) {
|
if (curDiag) {
|
||||||
GetLineClip(curDiag,curX1,curY1,curX2,curY2,inverse);
|
GetLineClip(curDiag,curX1,curY1,curX2,curY2,inverse);
|
||||||
PopulateFeatureList();
|
SetFeaturePositions();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,19 +59,20 @@ public:
|
||||||
class VisualToolClip : public VisualTool<ClipCorner> {
|
class VisualToolClip : public VisualTool<ClipCorner> {
|
||||||
int startX,startY,curX1,curY1,curX2,curY2;
|
int startX,startY,curX1,curY1,curX2,curY2;
|
||||||
|
|
||||||
|
ClipCorner *feats[4];
|
||||||
|
|
||||||
bool inverse;
|
bool inverse;
|
||||||
|
|
||||||
bool InitializeHold();
|
bool InitializeHold();
|
||||||
void UpdateHold();
|
void UpdateHold();
|
||||||
void CommitHold();
|
void CommitHold();
|
||||||
|
|
||||||
void OnLineChanged();
|
void DoRefresh();
|
||||||
void OnFileChanged();
|
void SetFeaturePositions();
|
||||||
|
|
||||||
void PopulateFeatureList();
|
bool InitializeDrag(feature_iterator feature);
|
||||||
bool InitializeDrag(ClipCorner* feature);
|
void UpdateDrag(feature_iterator feature);
|
||||||
void UpdateDrag(ClipCorner* feature);
|
void CommitDrag(feature_iterator feature);
|
||||||
void CommitDrag(ClipCorner* feature);
|
|
||||||
|
|
||||||
void Draw();
|
void Draw();
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -65,6 +65,9 @@ VisualToolDrag::VisualToolDrag(VideoDisplay *parent, VideoState const& video, wx
|
||||||
toolBar->AddTool(BUTTON_TOGGLE_MOVE, _("Toggle between \\move and \\pos"), GETIMAGE(visual_move_conv_move_24));
|
toolBar->AddTool(BUTTON_TOGGLE_MOVE, _("Toggle between \\move and \\pos"), GETIMAGE(visual_move_conv_move_24));
|
||||||
toolBar->Realize();
|
toolBar->Realize();
|
||||||
toolBar->Show(true);
|
toolBar->Show(true);
|
||||||
|
|
||||||
|
grid->GetSelectedSet(selection);
|
||||||
|
OnFileChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolDrag::UpdateToggleButtons() {
|
void VisualToolDrag::UpdateToggleButtons() {
|
||||||
|
@ -93,9 +96,8 @@ void VisualToolDrag::UpdateToggleButtons() {
|
||||||
/// @brief Toggle button pressed
|
/// @brief Toggle button pressed
|
||||||
/// @param event
|
/// @param event
|
||||||
void VisualToolDrag::OnSubTool(wxCommandEvent &) {
|
void VisualToolDrag::OnSubTool(wxCommandEvent &) {
|
||||||
Selection sel = grid->GetSelectedSet();
|
|
||||||
// Toggle \move <-> \pos
|
// Toggle \move <-> \pos
|
||||||
for (Selection::const_iterator cur = sel.begin(); cur != sel.end(); ++cur) {
|
for (Selection::const_iterator cur = selection.begin(); cur != selection.end(); ++cur) {
|
||||||
AssDialogue *line = *cur;
|
AssDialogue *line = *cur;
|
||||||
int x1,y1,x2,y2,t1,t2;
|
int x1,y1,x2,y2,t1,t2;
|
||||||
bool hasMove;
|
bool hasMove;
|
||||||
|
@ -118,31 +120,62 @@ void VisualToolDrag::OnLineChanged() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolDrag::OnFileChanged() {
|
void VisualToolDrag::OnFileChanged() {
|
||||||
/// @todo be less dumb and preserve selections when possible
|
/// @todo it should be possible to preserve the selection in some cases
|
||||||
PopulateFeatureList();
|
features.clear();
|
||||||
|
ClearSelection();
|
||||||
|
primary = NULL;
|
||||||
|
|
||||||
|
for (int i = grid->GetRows() - 1; i >=0; i--) {
|
||||||
|
AssDialogue *diag = grid->GetDialogue(i);
|
||||||
|
if (BaseGrid::IsDisplayed(diag)) {
|
||||||
|
MakeFeatures(diag);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolDrag::OnFrameChanged() {
|
void VisualToolDrag::OnFrameChanged() {
|
||||||
/// @todo be less dumb and preserve selections when possible
|
if (primary && !BaseGrid::IsDisplayed(primary->line)) primary = NULL;
|
||||||
PopulateFeatureList();
|
|
||||||
|
feature_iterator feat = features.begin();
|
||||||
|
feature_iterator end = features.end();
|
||||||
|
|
||||||
|
for (int i = grid->GetRows() - 1; i >=0; i--) {
|
||||||
|
AssDialogue *diag = grid->GetDialogue(i);
|
||||||
|
if (BaseGrid::IsDisplayed(diag)) {
|
||||||
|
// Features don't exist and should
|
||||||
|
if (feat == end || feat->line != diag) {
|
||||||
|
MakeFeatures(diag, feat);
|
||||||
|
}
|
||||||
|
// Move past already existing features for the line
|
||||||
|
else {
|
||||||
|
while (feat != end && feat->line == diag) ++feat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Remove all features for this line (if any)
|
||||||
|
while (feat != end && feat->line == diag) {
|
||||||
|
feat->line = NULL;
|
||||||
|
RemoveSelection(feat);
|
||||||
|
feat = features.erase(feat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolDrag::OnSelectedSetChanged(const Selection &added, const Selection &removed) {
|
void VisualToolDrag::OnSelectedSetChanged(const Selection &added, const Selection &removed) {
|
||||||
|
grid->GetSelectedSet(selection);
|
||||||
if (!externalChange) return;
|
if (!externalChange) return;
|
||||||
externalChange = false;
|
externalChange = false;
|
||||||
grid->BeginBatch();
|
grid->BeginBatch();
|
||||||
|
|
||||||
// Remove all deselected lines
|
for (feature_iterator cur = features.begin(); cur != features.end(); ++cur) {
|
||||||
for (size_t i = 0; i < features.size(); i++) {
|
// Remove all deselected lines
|
||||||
if (removed.find(features[i].line) != removed.end()) {
|
if (removed.find(cur->line) != removed.end()) {
|
||||||
RemoveSelection(i);
|
RemoveSelection(cur);
|
||||||
}
|
}
|
||||||
}
|
// And add all newly selected lines
|
||||||
|
else if (added.find(cur->line) != added.end() && cur->type == DRAG_START) {
|
||||||
// And add all newly selected lines
|
AddSelection(cur);
|
||||||
for (size_t i = 0; i < features.size(); i++) {
|
|
||||||
if (added.find(features[i].line) != added.end() && features[i].type == DRAG_START) {
|
|
||||||
AddSelection(i);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,8 +189,8 @@ void VisualToolDrag::Draw() {
|
||||||
// Draw arrows
|
// Draw arrows
|
||||||
for (feature_iterator cur = features.begin(); cur != features.end(); ++cur) {
|
for (feature_iterator cur = features.begin(); cur != features.end(); ++cur) {
|
||||||
if (cur->type == DRAG_START) continue;
|
if (cur->type == DRAG_START) continue;
|
||||||
VisualDraggableFeature *p2 = &*cur;
|
feature_iterator p2 = cur;
|
||||||
VisualDraggableFeature *p1 = &features[cur->parent];
|
feature_iterator p1 = cur->parent;
|
||||||
|
|
||||||
// Has arrow?
|
// Has arrow?
|
||||||
bool hasArrow = p2->type == DRAG_END;
|
bool hasArrow = p2->type == DRAG_END;
|
||||||
|
@ -199,89 +232,77 @@ void VisualToolDrag::Draw() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
void VisualToolDrag::MakeFeatures(AssDialogue *diag) {
|
||||||
void VisualToolDrag::PopulateFeatureList() {
|
MakeFeatures(diag, features.end());
|
||||||
ClearSelection();
|
|
||||||
primary = -1;
|
|
||||||
GenerateFeatures();
|
|
||||||
}
|
}
|
||||||
void VisualToolDrag::GenerateFeatures() {
|
void VisualToolDrag::MakeFeatures(AssDialogue *diag, feature_iterator pos) {
|
||||||
features.clear();
|
// Get position
|
||||||
|
int x1,x2,y1,y2;
|
||||||
|
int t1=0;
|
||||||
|
int t2=diag->End.GetMS()-diag->Start.GetMS();
|
||||||
|
int torgx,torgy;
|
||||||
|
bool hasMove;
|
||||||
|
GetLinePosition(diag,x1,y1,torgx,torgy);
|
||||||
|
GetLineMove(diag,hasMove,x1,y1,x2,y2,t1,t2);
|
||||||
|
|
||||||
// Get video data
|
// Create \pos feature
|
||||||
BaseGrid* grid = VideoContext::Get()->grid;
|
Feature feat;
|
||||||
int numRows = grid->GetRows();
|
feat.x = x1;
|
||||||
|
feat.y = y1;
|
||||||
|
feat.layer = 0;
|
||||||
|
feat.type = DRAG_START;
|
||||||
|
feat.time = t1;
|
||||||
|
feat.line = diag;
|
||||||
|
feat.parent = features.end();
|
||||||
|
features.insert(pos, feat);
|
||||||
|
feature_iterator cur = pos; --cur;
|
||||||
|
feat.parent = cur;
|
||||||
|
if (selection.find(diag) != selection.end()) {
|
||||||
|
AddSelection(cur);
|
||||||
|
}
|
||||||
|
|
||||||
for (int i=numRows;--i>=0;) {
|
// Create move destination feature
|
||||||
AssDialogue *diag = grid->GetDialogue(i);
|
if (hasMove) {
|
||||||
if (!diag || !BaseGrid::IsDisplayed(diag)) continue;
|
feat.x = x2;
|
||||||
|
feat.y = y2;
|
||||||
// Get position
|
feat.layer = 1;
|
||||||
int x1,x2,y1,y2;
|
feat.type = DRAG_END;
|
||||||
int t1=0;
|
feat.time = t2;
|
||||||
int t2=diag->End.GetMS()-diag->Start.GetMS();
|
|
||||||
int torgx,torgy;
|
|
||||||
bool hasMove;
|
|
||||||
GetLinePosition(diag,x1,y1,torgx,torgy);
|
|
||||||
GetLineMove(diag,hasMove,x1,y1,x2,y2,t1,t2);
|
|
||||||
|
|
||||||
// Create \pos feature
|
|
||||||
VisualToolDragDraggableFeature feat;
|
|
||||||
feat.x = x1;
|
|
||||||
feat.y = y1;
|
|
||||||
feat.layer = 0;
|
|
||||||
feat.type = DRAG_START;
|
|
||||||
feat.time = t1;
|
|
||||||
feat.line = diag;
|
feat.line = diag;
|
||||||
feat.lineN = i;
|
features.insert(pos, feat);
|
||||||
features.push_back(feat);
|
feat.parent->parent = --pos; ++pos;
|
||||||
feat.parent = features.size() - 1;
|
}
|
||||||
if (grid->IsInSelection(i)) {
|
// Create org feature
|
||||||
AddSelection(features.size() - 1);
|
if (torgx != x1 || torgy != y1) {
|
||||||
}
|
feat.x = torgx;
|
||||||
|
feat.y = torgy;
|
||||||
// Create move destination feature
|
feat.layer = -1;
|
||||||
if (hasMove) {
|
feat.type = DRAG_ORIGIN;
|
||||||
feat.x = x2;
|
feat.time = 0;
|
||||||
feat.y = y2;
|
feat.line = diag;
|
||||||
feat.layer = 1;
|
features.insert(pos, feat);
|
||||||
feat.type = DRAG_END;
|
|
||||||
feat.time = t2;
|
|
||||||
feat.line = diag;
|
|
||||||
feat.lineN = i;
|
|
||||||
features.push_back(feat);
|
|
||||||
features[feat.parent].parent = features.size() - 1;
|
|
||||||
}
|
|
||||||
// Create org feature
|
|
||||||
if (torgx != x1 || torgy != y1) {
|
|
||||||
feat.x = torgx;
|
|
||||||
feat.y = torgy;
|
|
||||||
feat.layer = -1;
|
|
||||||
feat.type = DRAG_ORIGIN;
|
|
||||||
feat.time = 0;
|
|
||||||
feat.line = diag;
|
|
||||||
feat.lineN = i;
|
|
||||||
features.push_back(feat);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VisualToolDrag::InitializeDrag(VisualToolDragDraggableFeature *feature) {
|
bool VisualToolDrag::InitializeDrag(feature_iterator feature) {
|
||||||
primary = feature - &features[0];
|
primary = &*feature;
|
||||||
|
|
||||||
|
// Set time of clicked feature to the current frame and shift all other
|
||||||
|
// selected features by the same amount
|
||||||
|
if (feature->type != DRAG_ORIGIN) {
|
||||||
|
int time = VFR_Output.GetTimeAtFrame(frameNumber,true,true) - feature->line->Start.GetMS();
|
||||||
|
int change = time - feature->time;
|
||||||
|
|
||||||
|
for (sel_iterator cur = selectedFeatures.begin(); cur != selectedFeatures.end(); ++cur) {
|
||||||
|
if ((*cur)->type != DRAG_ORIGIN) {
|
||||||
|
(*cur)->time += change;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Update drag
|
void VisualToolDrag::CommitDrag(feature_iterator feature) {
|
||||||
/// @param feature
|
|
||||||
void VisualToolDrag::UpdateDrag(VisualToolDragDraggableFeature* feature) {
|
|
||||||
// Update "time" to reflect the time of the frame in which the feature is being dragged
|
|
||||||
int time = VFR_Output.GetTimeAtFrame(frameNumber,true,true);
|
|
||||||
feature->time = MID(0,time - feature->line->Start.GetMS(),feature->line->End.GetMS()-feature->line->Start.GetMS());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @brief Commit drag
|
|
||||||
/// @param feature
|
|
||||||
void VisualToolDrag::CommitDrag(VisualToolDragDraggableFeature* feature) {
|
|
||||||
if (feature->type == DRAG_ORIGIN) {
|
if (feature->type == DRAG_ORIGIN) {
|
||||||
int x = feature->x;
|
int x = feature->x;
|
||||||
int y = feature->y;
|
int y = feature->y;
|
||||||
|
@ -290,7 +311,7 @@ void VisualToolDrag::CommitDrag(VisualToolDragDraggableFeature* feature) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
VisualToolDragDraggableFeature *p = feature->parent > -1 ? &features[feature->parent] : NULL;
|
feature_iterator p = feature->parent;
|
||||||
if (feature->type == DRAG_END) {
|
if (feature->type == DRAG_END) {
|
||||||
std::swap(feature, p);
|
std::swap(feature, p);
|
||||||
}
|
}
|
||||||
|
@ -300,7 +321,7 @@ void VisualToolDrag::CommitDrag(VisualToolDragDraggableFeature* feature) {
|
||||||
parent->ToScriptCoords(&x1, &y1);
|
parent->ToScriptCoords(&x1, &y1);
|
||||||
|
|
||||||
// Position
|
// Position
|
||||||
if (!p) {
|
if (feature->parent == features.end()) {
|
||||||
SetOverride(feature->line, L"\\pos", wxString::Format(L"(%i,%i)", x1, y1));
|
SetOverride(feature->line, L"\\pos", wxString::Format(L"(%i,%i)", x1, y1));
|
||||||
}
|
}
|
||||||
// Move
|
// Move
|
||||||
|
@ -309,7 +330,6 @@ void VisualToolDrag::CommitDrag(VisualToolDragDraggableFeature* feature) {
|
||||||
int y2 = p->y;
|
int y2 = p->y;
|
||||||
parent->ToScriptCoords(&x2, &y2);
|
parent->ToScriptCoords(&x2, &y2);
|
||||||
|
|
||||||
// Set override
|
|
||||||
SetOverride(feature->line, L"\\move", wxString::Format(L"(%i,%i,%i,%i,%i,%i)", x1, y1, x2, y2, feature->time, p->time));
|
SetOverride(feature->line, L"\\move", wxString::Format(L"(%i,%i,%i,%i,%i,%i)", x1, y1, x2, y2, feature->time, p->time));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -320,9 +340,9 @@ bool VisualToolDrag::Update() {
|
||||||
int vx = video.x;
|
int vx = video.x;
|
||||||
int vy = video.y;
|
int vy = video.y;
|
||||||
parent->ToScriptCoords(&vx, &vy);
|
parent->ToScriptCoords(&vx, &vy);
|
||||||
if (primary > -1) {
|
if (primary) {
|
||||||
dx = features[primary].x;
|
dx = primary->x;
|
||||||
dy = features[primary].y;
|
dy = primary->y;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (!curDiag) return false;
|
if (!curDiag) return false;
|
||||||
|
@ -332,8 +352,7 @@ bool VisualToolDrag::Update() {
|
||||||
dx -= vx;
|
dx -= vx;
|
||||||
dy -= vy;
|
dy -= vy;
|
||||||
|
|
||||||
Selection sel = grid->GetSelectedSet();
|
for (Selection::const_iterator cur = selection.begin(); cur != selection.end(); ++cur) {
|
||||||
for (Selection::const_iterator cur = sel.begin(); cur != sel.end(); ++cur) {
|
|
||||||
int x1 = 0, y1 = 0, x2 = 0, y2 = 0, t1 = INT_MIN, t2 = INT_MIN, orgx, orgy;
|
int x1 = 0, y1 = 0, x2 = 0, y2 = 0, t1 = INT_MIN, t2 = INT_MIN, orgx, orgy;
|
||||||
bool isMove;
|
bool isMove;
|
||||||
|
|
||||||
|
@ -359,6 +378,6 @@ bool VisualToolDrag::Update() {
|
||||||
|
|
||||||
Commit(true, _("positioning"));
|
Commit(true, _("positioning"));
|
||||||
|
|
||||||
GenerateFeatures();
|
OnFileChanged();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,12 +47,8 @@
|
||||||
class VisualToolDragDraggableFeature : public VisualDraggableFeature {
|
class VisualToolDragDraggableFeature : public VisualDraggableFeature {
|
||||||
public:
|
public:
|
||||||
int time;
|
int time;
|
||||||
int parent;
|
std::list<VisualToolDragDraggableFeature>::iterator parent;
|
||||||
VisualToolDragDraggableFeature()
|
VisualToolDragDraggableFeature() : VisualDraggableFeature(), time(0) { }
|
||||||
: VisualDraggableFeature()
|
|
||||||
, time(0)
|
|
||||||
, parent(-1)
|
|
||||||
{ }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -62,21 +58,29 @@ public:
|
||||||
///
|
///
|
||||||
/// DOCME
|
/// DOCME
|
||||||
class VisualToolDrag : public VisualTool<VisualToolDragDraggableFeature> {
|
class VisualToolDrag : public VisualTool<VisualToolDragDraggableFeature> {
|
||||||
private:
|
/// The subtoolbar for the move/pos conversion button
|
||||||
wxToolBar *toolBar; /// The subtoolbar
|
wxToolBar *toolBar;
|
||||||
int primary; /// The feature last clicked on
|
/// The feature last clicked on for the double-click handler
|
||||||
|
/// Equal to curFeature during drags; possibly different at all other times
|
||||||
|
/// Null if no features have been clicked on or the last clicked on one no
|
||||||
|
/// longer exists
|
||||||
|
Feature *primary;
|
||||||
|
/// The last announced selection set
|
||||||
|
Selection selection;
|
||||||
|
int change;
|
||||||
|
|
||||||
/// When the button is pressed, will it convert the line to a move (vs. from
|
/// When the button is pressed, will it convert the line to a move (vs. from
|
||||||
/// move to pos)? Used to avoid changing the button's icon unnecessarily
|
/// move to pos)? Used to avoid changing the button's icon unnecessarily
|
||||||
bool toggleMoveOnMove;
|
bool toggleMoveOnMove;
|
||||||
|
|
||||||
/// Regenerage features without touching the selection
|
/// @brief Create the features for a line
|
||||||
void GenerateFeatures();
|
/// @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);
|
||||||
|
|
||||||
void PopulateFeatureList();
|
bool InitializeDrag(feature_iterator feature);
|
||||||
bool InitializeDrag(VisualToolDragDraggableFeature* feature);
|
void CommitDrag(feature_iterator feature);
|
||||||
void UpdateDrag(VisualToolDragDraggableFeature* feature);
|
|
||||||
void CommitDrag(VisualToolDragDraggableFeature* feature);
|
|
||||||
|
|
||||||
/// Set the pos/move button to the correct icon based on the active line
|
/// Set the pos/move button to the correct icon based on the active line
|
||||||
void UpdateToggleButtons();
|
void UpdateToggleButtons();
|
||||||
|
|
|
@ -51,6 +51,9 @@
|
||||||
VisualToolRotateXY::VisualToolRotateXY(VideoDisplay *parent, VideoState const& video, wxToolBar *)
|
VisualToolRotateXY::VisualToolRotateXY(VideoDisplay *parent, VideoState const& video, wxToolBar *)
|
||||||
: VisualTool<VisualDraggableFeature>(parent, video)
|
: VisualTool<VisualDraggableFeature>(parent, video)
|
||||||
{
|
{
|
||||||
|
features.resize(1);
|
||||||
|
org = &features.back();
|
||||||
|
org->type = DRAG_BIG_TRIANGLE;
|
||||||
DoRefresh();
|
DoRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,9 +63,9 @@ void VisualToolRotateXY::Draw() {
|
||||||
// Pivot coordinates
|
// Pivot coordinates
|
||||||
int dx=0,dy=0;
|
int dx=0,dy=0;
|
||||||
if (dragging) GetLinePosition(curDiag,dx,dy);
|
if (dragging) GetLinePosition(curDiag,dx,dy);
|
||||||
else GetLinePosition(curDiag,dx,dy,orgx,orgy);
|
else GetLinePosition(curDiag,dx,dy,org->x,org->y);
|
||||||
dx = orgx;
|
dx = org->x;
|
||||||
dy = orgy;
|
dy = org->y;
|
||||||
|
|
||||||
SetLineColour(colour[0]);
|
SetLineColour(colour[0]);
|
||||||
SetFillColour(colour[1],0.3f);
|
SetFillColour(colour[1],0.3f);
|
||||||
|
@ -152,8 +155,8 @@ void VisualToolRotateXY::Draw() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VisualToolRotateXY::InitializeHold() {
|
bool VisualToolRotateXY::InitializeHold() {
|
||||||
startAngleX = (orgy-video.y)*2.f;
|
startAngleX = (org->y-video.y)*2.f;
|
||||||
startAngleY = (video.x-orgx)*2.f;
|
startAngleY = (video.x-org->x)*2.f;
|
||||||
origAngleX = curAngleX;
|
origAngleX = curAngleX;
|
||||||
origAngleY = curAngleY;
|
origAngleY = curAngleY;
|
||||||
|
|
||||||
|
@ -161,8 +164,8 @@ bool VisualToolRotateXY::InitializeHold() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolRotateXY::UpdateHold() {
|
void VisualToolRotateXY::UpdateHold() {
|
||||||
float screenAngleX = (orgy-video.y)*2.f;
|
float screenAngleX = (org->y-video.y)*2.f;
|
||||||
float screenAngleY = (video.x-orgx)*2.f;
|
float screenAngleY = (video.x-org->x)*2.f;
|
||||||
|
|
||||||
// Deltas
|
// Deltas
|
||||||
float deltaX = screenAngleX - startAngleX;
|
float deltaX = screenAngleX - startAngleX;
|
||||||
|
@ -193,36 +196,16 @@ void VisualToolRotateXY::CommitHold() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolRotateXY::PopulateFeatureList() {
|
void VisualToolRotateXY::CommitDrag(feature_iterator feature) {
|
||||||
if (!curDiag) return;
|
|
||||||
|
|
||||||
int posx, posy;
|
|
||||||
GetLinePosition(curDiag,posx,posy,orgx,orgy);
|
|
||||||
|
|
||||||
// Set features
|
|
||||||
features.resize(1);
|
|
||||||
VisualDraggableFeature &feat = features.back();
|
|
||||||
feat.x = orgx;
|
|
||||||
feat.y = orgy;
|
|
||||||
feat.line = curDiag;
|
|
||||||
feat.type = DRAG_BIG_TRIANGLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VisualToolRotateXY::UpdateDrag(VisualDraggableFeature* feature) {
|
|
||||||
orgx = feature->x;
|
|
||||||
orgy = feature->y;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VisualToolRotateXY::CommitDrag(VisualDraggableFeature* feature) {
|
|
||||||
int x = feature->x;
|
int x = feature->x;
|
||||||
int y = feature->y;
|
int y = feature->y;
|
||||||
parent->ToScriptCoords(&x, &y);
|
parent->ToScriptCoords(&x, &y);
|
||||||
SetOverride(feature->line, L"\\org",wxString::Format(L"(%i,%i)",x,y));
|
SetOverride(curDiag, L"\\org",wxString::Format(L"(%i,%i)",x,y));
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolRotateXY::DoRefresh() {
|
void VisualToolRotateXY::DoRefresh() {
|
||||||
if (!curDiag) return;
|
if (!curDiag) return;
|
||||||
int posx, posy;
|
int posx, posy;
|
||||||
GetLinePosition(curDiag,posx,posy,orgx,orgy);
|
GetLinePosition(curDiag,posx,posy,org->x,org->y);
|
||||||
GetLineRotation(curDiag,curAngleX,curAngleY,curAngleZ);
|
GetLineRotation(curDiag,curAngleX,curAngleY,curAngleZ);
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,16 +44,13 @@ class VisualToolRotateXY : public VisualTool<VisualDraggableFeature> {
|
||||||
float curAngleX,startAngleX,origAngleX;
|
float curAngleX,startAngleX,origAngleX;
|
||||||
float curAngleY,startAngleY,origAngleY;
|
float curAngleY,startAngleY,origAngleY;
|
||||||
float curAngleZ;
|
float curAngleZ;
|
||||||
int orgx,orgy;
|
Feature *org;
|
||||||
|
|
||||||
bool InitializeHold();
|
bool InitializeHold();
|
||||||
void UpdateHold();
|
void UpdateHold();
|
||||||
void CommitHold();
|
void CommitHold();
|
||||||
|
|
||||||
|
void CommitDrag(feature_iterator feature);
|
||||||
void PopulateFeatureList();
|
|
||||||
void UpdateDrag(VisualDraggableFeature* feature);
|
|
||||||
void CommitDrag(VisualDraggableFeature* feature);
|
|
||||||
|
|
||||||
void DoRefresh();
|
void DoRefresh();
|
||||||
|
|
||||||
|
|
|
@ -54,6 +54,9 @@ static const float rad2deg = 180.f / 3.1415926536f;
|
||||||
VisualToolRotateZ::VisualToolRotateZ(VideoDisplay *parent, VideoState const& video, wxToolBar *)
|
VisualToolRotateZ::VisualToolRotateZ(VideoDisplay *parent, VideoState const& video, wxToolBar *)
|
||||||
: VisualTool<VisualDraggableFeature>(parent, video)
|
: VisualTool<VisualDraggableFeature>(parent, video)
|
||||||
{
|
{
|
||||||
|
features.resize(1);
|
||||||
|
org = &features.back();
|
||||||
|
org->type = DRAG_BIG_TRIANGLE;
|
||||||
DoRefresh();
|
DoRefresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +66,7 @@ void VisualToolRotateZ::Draw() {
|
||||||
// Draw pivot
|
// Draw pivot
|
||||||
DrawAllFeatures();
|
DrawAllFeatures();
|
||||||
|
|
||||||
int radius = (int)sqrt(double((posx-orgx)*(posx-orgx)+(posy-orgy)*(posy-orgy)));
|
int radius = (int)sqrt(double((posx-org->x)*(posx-org->x)+(posy-org->y)*(posy-org->y)));
|
||||||
int oRadius = radius;
|
int oRadius = radius;
|
||||||
if (radius < 50) radius = 50;
|
if (radius < 50) radius = 50;
|
||||||
|
|
||||||
|
@ -78,7 +81,7 @@ void VisualToolRotateZ::Draw() {
|
||||||
glMatrixMode(GL_MODELVIEW);
|
glMatrixMode(GL_MODELVIEW);
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
glTranslatef(orgx,orgy,-1.f);
|
glTranslatef(org->x,org->y,-1.f);
|
||||||
float matrix[16] = { 2500, 0, 0, 0, 0, 2500, 0, 0, 0, 0, 1, 1, 0, 0, 2500, 2500 };
|
float matrix[16] = { 2500, 0, 0, 0, 0, 2500, 0, 0, 0, 0, 1, 1, 0, 0, 2500, 2500 };
|
||||||
glMultMatrixf(matrix);
|
glMultMatrixf(matrix);
|
||||||
glScalef(1.f,1.f,8.f);
|
glScalef(1.f,1.f,8.f);
|
||||||
|
@ -103,8 +106,8 @@ void VisualToolRotateZ::Draw() {
|
||||||
DrawLine(deltax,deltay,-deltax,-deltay);
|
DrawLine(deltax,deltay,-deltax,-deltay);
|
||||||
|
|
||||||
// Draw the connection line
|
// Draw the connection line
|
||||||
if (orgx != posx || orgy != posy) {
|
if (org->x != posx || org->y != posy) {
|
||||||
double angle = atan2(double(orgy-posy),double(posx-orgx)) + curAngle*deg2rad;
|
double angle = atan2(double(org->y-posy),double(posx-org->x)) + curAngle*deg2rad;
|
||||||
int fx = int(cos(angle)*oRadius);
|
int fx = int(cos(angle)*oRadius);
|
||||||
int fy = -int(sin(angle)*oRadius);
|
int fy = -int(sin(angle)*oRadius);
|
||||||
DrawLine(0,0,fx,fy);
|
DrawLine(0,0,fx,fy);
|
||||||
|
@ -121,14 +124,14 @@ void VisualToolRotateZ::Draw() {
|
||||||
glPopMatrix();
|
glPopMatrix();
|
||||||
|
|
||||||
// Draw line to mouse
|
// Draw line to mouse
|
||||||
if (!dragging && !curFeature && video.x > INT_MIN && video.y > INT_MIN) {
|
if (!dragging && curFeature == features.end() && video.x > INT_MIN && video.y > INT_MIN) {
|
||||||
SetLineColour(colour[0]);
|
SetLineColour(colour[0]);
|
||||||
DrawLine(orgx,orgy,video.x,video.y);
|
DrawLine(org->x,org->y,video.x,video.y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VisualToolRotateZ::InitializeHold() {
|
bool VisualToolRotateZ::InitializeHold() {
|
||||||
startAngle = atan2(double(orgy-video.y),double(video.x-orgx)) * rad2deg;
|
startAngle = atan2(double(org->y-video.y),double(video.x-org->x)) * rad2deg;
|
||||||
origAngle = curAngle;
|
origAngle = curAngle;
|
||||||
curDiag->StripTag(L"\\frz");
|
curDiag->StripTag(L"\\frz");
|
||||||
curDiag->StripTag(L"\\fr");
|
curDiag->StripTag(L"\\fr");
|
||||||
|
@ -137,7 +140,7 @@ bool VisualToolRotateZ::InitializeHold() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolRotateZ::UpdateHold() {
|
void VisualToolRotateZ::UpdateHold() {
|
||||||
float screenAngle = atan2(double(orgy-video.y),double(video.x-orgx)) * rad2deg;
|
float screenAngle = atan2(double(org->y-video.y),double(video.x-org->x)) * rad2deg;
|
||||||
curAngle = fmodf(screenAngle - startAngle + origAngle + 360.f, 360.f);
|
curAngle = fmodf(screenAngle - startAngle + origAngle + 360.f, 360.f);
|
||||||
|
|
||||||
// Oh Snap
|
// Oh Snap
|
||||||
|
@ -154,33 +157,16 @@ void VisualToolRotateZ::CommitHold() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolRotateZ::PopulateFeatureList() {
|
void VisualToolRotateZ::CommitDrag(feature_iterator feature) {
|
||||||
if (!curDiag) return;
|
|
||||||
|
|
||||||
// Set features
|
|
||||||
features.resize(1);
|
|
||||||
VisualDraggableFeature &feat = features.back();
|
|
||||||
feat.x = orgx;
|
|
||||||
feat.y = orgy;
|
|
||||||
feat.line = curDiag;
|
|
||||||
feat.type = DRAG_BIG_TRIANGLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VisualToolRotateZ::UpdateDrag(VisualDraggableFeature* feature) {
|
|
||||||
orgx = feature->x;
|
|
||||||
orgy = feature->y;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VisualToolRotateZ::CommitDrag(VisualDraggableFeature* feature) {
|
|
||||||
int x = feature->x;
|
int x = feature->x;
|
||||||
int y = feature->y;
|
int y = feature->y;
|
||||||
parent->ToScriptCoords(&x, &y);
|
parent->ToScriptCoords(&x, &y);
|
||||||
SetOverride(feature->line, L"\\org",wxString::Format(L"(%i,%i)",x,y));
|
SetOverride(curDiag, L"\\org",wxString::Format(L"(%i,%i)",x,y));
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolRotateZ::DoRefresh() {
|
void VisualToolRotateZ::DoRefresh() {
|
||||||
if (!curDiag) return;
|
if (!curDiag) return;
|
||||||
GetLinePosition(curDiag, posx, posy, orgx, orgy);
|
GetLinePosition(curDiag, posx, posy, org->x, org->y);
|
||||||
GetLineRotation(curDiag, rx, ry, curAngle);
|
GetLineRotation(curDiag, rx, ry, curAngle);
|
||||||
GetLineScale(curDiag, scaleX, scaleY);
|
GetLineScale(curDiag, scaleX, scaleY);
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@
|
||||||
/// DOCME
|
/// DOCME
|
||||||
class VisualToolRotateZ : public VisualTool<VisualDraggableFeature> {
|
class VisualToolRotateZ : public VisualTool<VisualDraggableFeature> {
|
||||||
float curAngle, startAngle, origAngle;
|
float curAngle, startAngle, origAngle;
|
||||||
int orgx, orgy;
|
Feature *org;
|
||||||
int posx, posy;
|
int posx, posy;
|
||||||
float rx, ry;
|
float rx, ry;
|
||||||
float scaleX, scaleY;
|
float scaleX, scaleY;
|
||||||
|
@ -54,9 +54,7 @@ class VisualToolRotateZ : public VisualTool<VisualDraggableFeature> {
|
||||||
void UpdateHold();
|
void UpdateHold();
|
||||||
void CommitHold();
|
void CommitHold();
|
||||||
|
|
||||||
void PopulateFeatureList();
|
void CommitDrag(feature_iterator feature);
|
||||||
void UpdateDrag(VisualDraggableFeature* feature);
|
|
||||||
void CommitDrag(VisualDraggableFeature* feature);
|
|
||||||
|
|
||||||
void DoRefresh();
|
void DoRefresh();
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,7 @@
|
||||||
|
|
||||||
#include "ass_dialogue.h"
|
#include "ass_dialogue.h"
|
||||||
#include "libresrc/libresrc.h"
|
#include "libresrc/libresrc.h"
|
||||||
|
#include "utils.h"
|
||||||
#include "video_display.h"
|
#include "video_display.h"
|
||||||
#include "visual_tool_vector_clip.h"
|
#include "visual_tool_vector_clip.h"
|
||||||
|
|
||||||
|
@ -69,12 +70,19 @@ enum {
|
||||||
BUTTON_LAST // Leave this at the end and don't use it
|
BUTTON_LAST // Leave this at the end and don't use it
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<class C, class O, class M>
|
||||||
|
static void for_each_iter(C &container, O obj, M method) {
|
||||||
|
C::iterator end = container.end();
|
||||||
|
for (C::iterator cur = container.begin(); cur != end; ++cur) {
|
||||||
|
(obj ->* method)(cur);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VisualToolVectorClip::VisualToolVectorClip(VideoDisplay *parent, VideoState const& video, wxToolBar * toolBar)
|
VisualToolVectorClip::VisualToolVectorClip(VideoDisplay *parent, VideoState const& video, wxToolBar * toolBar)
|
||||||
: VisualTool<VisualToolVectorClipDraggableFeature>(parent, video)
|
: VisualTool<VisualToolVectorClipDraggableFeature>(parent, video)
|
||||||
, spline(*parent)
|
, spline(*parent)
|
||||||
, toolBar(toolBar)
|
, toolBar(toolBar)
|
||||||
{
|
{
|
||||||
// Create toolbar
|
|
||||||
toolBar->AddTool(BUTTON_DRAG,_("Drag"),GETIMAGE(visual_vector_clip_drag_24),_("Drag control points."),wxITEM_CHECK);
|
toolBar->AddTool(BUTTON_DRAG,_("Drag"),GETIMAGE(visual_vector_clip_drag_24),_("Drag control points."),wxITEM_CHECK);
|
||||||
toolBar->AddTool(BUTTON_LINE,_("Line"),GETIMAGE(visual_vector_clip_line_24),_("Appends a line."),wxITEM_CHECK);
|
toolBar->AddTool(BUTTON_LINE,_("Line"),GETIMAGE(visual_vector_clip_line_24),_("Appends a line."),wxITEM_CHECK);
|
||||||
toolBar->AddTool(BUTTON_BICUBIC,_("Bicubic"),GETIMAGE(visual_vector_clip_bicubic_24),_("Appends a bezier bicubic curve."),wxITEM_CHECK);
|
toolBar->AddTool(BUTTON_BICUBIC,_("Bicubic"),GETIMAGE(visual_vector_clip_bicubic_24),_("Appends a bezier bicubic curve."),wxITEM_CHECK);
|
||||||
|
@ -184,7 +192,7 @@ void VisualToolVectorClip::Draw() {
|
||||||
spline.GetClosestParametricPoint(Vector2D(video.x, video.y), highCurve, t, pt);
|
spline.GetClosestParametricPoint(Vector2D(video.x, video.y), highCurve, t, pt);
|
||||||
|
|
||||||
// Draw highlighted line
|
// Draw highlighted line
|
||||||
if ((mode == 3 || mode == 4) && !curFeature && points.size() > 2) {
|
if ((mode == 3 || mode == 4) && curFeature == features.end() && points.size() > 2) {
|
||||||
std::vector<float> highPoints;
|
std::vector<float> highPoints;
|
||||||
spline.GetPointList(highPoints, highCurve);
|
spline.GetPointList(highPoints, highCurve);
|
||||||
if (!highPoints.empty()) {
|
if (!highPoints.empty()) {
|
||||||
|
@ -223,7 +231,7 @@ void VisualToolVectorClip::Draw() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolVectorClip::MakeFeature(Spline::iterator cur) {
|
void VisualToolVectorClip::MakeFeature(Spline::iterator cur) {
|
||||||
VisualToolVectorClipDraggableFeature feat;
|
Feature feat;
|
||||||
if (cur->type == CURVE_POINT) {
|
if (cur->type == CURVE_POINT) {
|
||||||
feat.x = (int)cur->p1.x;
|
feat.x = (int)cur->p1.x;
|
||||||
feat.y = (int)cur->p1.y;
|
feat.y = (int)cur->p1.y;
|
||||||
|
@ -250,6 +258,7 @@ void VisualToolVectorClip::MakeFeature(Spline::iterator cur) {
|
||||||
feat.point = 1;
|
feat.point = 1;
|
||||||
feat.type = DRAG_SMALL_SQUARE;
|
feat.type = DRAG_SMALL_SQUARE;
|
||||||
features.push_back(feat);
|
features.push_back(feat);
|
||||||
|
|
||||||
feat.x = (int)cur->p3.x;
|
feat.x = (int)cur->p3.x;
|
||||||
feat.y = (int)cur->p3.y;
|
feat.y = (int)cur->p3.y;
|
||||||
feat.point = 2;
|
feat.point = 2;
|
||||||
|
@ -264,28 +273,33 @@ void VisualToolVectorClip::MakeFeature(Spline::iterator cur) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolVectorClip::PopulateFeatureList() {
|
void VisualToolVectorClip::MakeFeatures() {
|
||||||
|
ClearSelection();
|
||||||
features.clear();
|
features.clear();
|
||||||
// This is perhaps a bit conservative as there can be up to 3N+1 features
|
for_each_iter(spline, this, &VisualToolVectorClip::MakeFeature);
|
||||||
features.reserve(spline.size());
|
|
||||||
|
|
||||||
for (Spline::iterator cur = spline.begin(); cur != spline.end(); ++cur) {
|
|
||||||
MakeFeature(cur);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolVectorClip::UpdateDrag(VisualToolVectorClipDraggableFeature* feature) {
|
void VisualToolVectorClip::Save() {
|
||||||
spline.MovePoint(feature->curve,feature->point,Vector2D(feature->x,feature->y));
|
|
||||||
}
|
|
||||||
|
|
||||||
void VisualToolVectorClip::CommitDrag(VisualToolVectorClipDraggableFeature*) {
|
|
||||||
SetOverride(curDiag, inverse ? L"\\iclip" : L"\\clip", L"(" + spline.EncodeToASS() + L")");
|
SetOverride(curDiag, inverse ? L"\\iclip" : L"\\clip", L"(" + spline.EncodeToASS() + L")");
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VisualToolVectorClip::InitializeDrag(VisualToolVectorClipDraggableFeature* feature) {
|
void VisualToolVectorClip::UpdateDrag(feature_iterator feature) {
|
||||||
// Delete a control point
|
spline.MovePoint(feature->curve,feature->point,Vector2D(feature->x,feature->y));
|
||||||
if (mode == 5) {
|
}
|
||||||
// Update next
|
|
||||||
|
void VisualToolVectorClip::CommitDrag(feature_iterator) {
|
||||||
|
Save();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool VisualToolVectorClip::InitializeDrag(feature_iterator feature) {
|
||||||
|
if (mode != 5) return true;
|
||||||
|
|
||||||
|
if (feature->curve->type == CURVE_BICUBIC && (feature->point == 1 || feature->point == 2)) {
|
||||||
|
// Deleting bicubic curve handles, so convert to line
|
||||||
|
feature->curve->type = CURVE_LINE;
|
||||||
|
feature->curve->p2 = feature->curve->p4;
|
||||||
|
}
|
||||||
|
else {
|
||||||
Spline::iterator next = feature->curve;
|
Spline::iterator next = feature->curve;
|
||||||
next++;
|
next++;
|
||||||
if (next != spline.end()) {
|
if (next != spline.end()) {
|
||||||
|
@ -298,16 +312,15 @@ bool VisualToolVectorClip::InitializeDrag(VisualToolVectorClipDraggableFeature*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Erase and save changes
|
|
||||||
spline.erase(feature->curve);
|
spline.erase(feature->curve);
|
||||||
CommitDrag(feature);
|
|
||||||
curFeature = NULL;
|
|
||||||
PopulateFeatureList();
|
|
||||||
ClearSelection();
|
|
||||||
Commit(true);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
return true;
|
curFeature = features.end();
|
||||||
|
|
||||||
|
Save();
|
||||||
|
MakeFeatures();
|
||||||
|
Commit(true, _("delete control point"));
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VisualToolVectorClip::InitializeHold() {
|
bool VisualToolVectorClip::InitializeHold() {
|
||||||
|
@ -318,8 +331,7 @@ bool VisualToolVectorClip::InitializeHold() {
|
||||||
// Set start position
|
// Set start position
|
||||||
if (!spline.empty()) {
|
if (!spline.empty()) {
|
||||||
curve.p1 = spline.back().EndPoint();
|
curve.p1 = spline.back().EndPoint();
|
||||||
if (mode == 1) curve.type = CURVE_LINE;
|
curve.type = mode == 1 ? CURVE_LINE : CURVE_BICUBIC;
|
||||||
else curve.type = CURVE_BICUBIC;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// First point
|
// First point
|
||||||
|
@ -383,9 +395,9 @@ bool VisualToolVectorClip::InitializeHold() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Commit
|
// Commit
|
||||||
SetOverride(curDiag, inverse ? L"\\iclip" : L"\\clip", L"(" + spline.EncodeToASS() + L")");
|
Save();
|
||||||
|
MakeFeatures();
|
||||||
Commit(true);
|
Commit(true);
|
||||||
DoRefresh();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,7 +442,7 @@ void VisualToolVectorClip::UpdateHold() {
|
||||||
}
|
}
|
||||||
else curve.p2 = curve.p1 * 0.75 + curve.p4 * 0.25;
|
else curve.p2 = curve.p1 * 0.75 + curve.p4 * 0.25;
|
||||||
curve.p3 = curve.p1 * 0.25 + curve.p4 * 0.75;
|
curve.p3 = curve.p1 * 0.25 + curve.p4 * 0.75;
|
||||||
PopulateFeatureList();
|
MakeFeatures();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Freehand
|
// Freehand
|
||||||
|
@ -452,21 +464,19 @@ void VisualToolVectorClip::UpdateHold() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolVectorClip::CommitHold() {
|
void VisualToolVectorClip::CommitHold() {
|
||||||
|
if (mode == 3 || mode == 4) return;
|
||||||
|
|
||||||
// Smooth spline
|
// Smooth spline
|
||||||
if (!holding && mode == 7) {
|
if (!holding && mode == 7) {
|
||||||
spline.Smooth();
|
spline.Smooth();
|
||||||
PopulateFeatureList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save it
|
Save();
|
||||||
if (mode != 3 && mode != 4) {
|
|
||||||
SetOverride(curDiag, inverse ? L"\\iclip" : L"\\clip", L"(" + spline.EncodeToASS() + L")");
|
|
||||||
}
|
|
||||||
|
|
||||||
// End freedraw
|
// End freedraw
|
||||||
if (!holding && (mode == 6 || mode == 7)) {
|
if (!holding && (mode == 6 || mode == 7)) {
|
||||||
SetMode(0);
|
SetMode(0);
|
||||||
SelectAll();
|
MakeFeatures();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -477,13 +487,12 @@ void VisualToolVectorClip::DoRefresh() {
|
||||||
int scale;
|
int scale;
|
||||||
vect = GetLineVectorClip(curDiag,scale,inverse);
|
vect = GetLineVectorClip(curDiag,scale,inverse);
|
||||||
spline.DecodeFromASS(vect);
|
spline.DecodeFromASS(vect);
|
||||||
|
|
||||||
|
MakeFeatures();
|
||||||
SelectAll();
|
SelectAll();
|
||||||
PopulateFeatureList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolVectorClip::SelectAll() {
|
void VisualToolVectorClip::SelectAll() {
|
||||||
ClearSelection();
|
ClearSelection();
|
||||||
for (size_t i = 0; i < features.size(); ++i) {
|
for_each_iter(features, this, &VisualToolVectorClip::AddSelection);
|
||||||
AddSelection(i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,17 +69,19 @@ class VisualToolVectorClip : public VisualTool<VisualToolVectorClipDraggableFeat
|
||||||
/// @param mode 0-7
|
/// @param mode 0-7
|
||||||
void SetMode(int mode);
|
void SetMode(int mode);
|
||||||
|
|
||||||
|
void Save();
|
||||||
|
|
||||||
void SelectAll();
|
void SelectAll();
|
||||||
void MakeFeature(Spline::iterator cur);
|
void MakeFeature(Spline::iterator cur);
|
||||||
|
void MakeFeatures();
|
||||||
|
|
||||||
bool InitializeHold();
|
bool InitializeHold();
|
||||||
void UpdateHold();
|
void UpdateHold();
|
||||||
void CommitHold();
|
void CommitHold();
|
||||||
|
|
||||||
void PopulateFeatureList();
|
void UpdateDrag(feature_iterator feature);
|
||||||
void UpdateDrag(VisualToolVectorClipDraggableFeature* feature);
|
void CommitDrag(feature_iterator feature);
|
||||||
void CommitDrag(VisualToolVectorClipDraggableFeature* feature);
|
bool InitializeDrag(feature_iterator feature);
|
||||||
bool InitializeDrag(VisualToolVectorClipDraggableFeature* feature);
|
|
||||||
|
|
||||||
void DoRefresh();
|
void DoRefresh();
|
||||||
void Draw();
|
void Draw();
|
||||||
|
|
Loading…
Reference in a new issue