Significantly revamp how visual tools interact with the rest of the program

Rather than just have a single Refresh method that gets called whenever
something happens that could possibly be of interest to the visual
tools, add seperate methods for signaling frame number changes and
changes to the file, and use the new SelectionController stuff for other
things that used to merit a Refresh. This eliminates a large amount of
redundant reparsing of lines which happened on paint, as well as a large
number of redundant repaints.

Frame data is now only uploaded to the video card when the frame number changes
rather than when anything at all changes, slightly improving performance when
using mesa's software opengl implementation.

Vector clip and drag tools now do a slightly better job of not
discarding the user's selection for no apparent reason, and strange
selection behavior from clicking on visual features should now be
entirely fixed.

Everything but the constructor and toolbar event handler in the visual
tool implementations are now private.

Originally committed to SVN as r4631.
This commit is contained in:
Thomas Goyne 2010-06-28 07:13:15 +00:00
parent d30326b20d
commit 5588cda268
20 changed files with 381 additions and 553 deletions

View file

@ -229,6 +229,7 @@ void VideoContext::SetVideo(const wxString &filename) {
// Choose a provider // Choose a provider
provider = VideoProviderFactoryManager::GetProvider(filename); provider = VideoProviderFactoryManager::GetProvider(filename);
loaded = provider != NULL;
// Get subtitles provider // Get subtitles provider
try { try {
@ -288,14 +289,13 @@ void VideoContext::SetVideo(const wxString &filename) {
hasSubtitles = MatroskaWrapper::HasSubtitles(filename); hasSubtitles = MatroskaWrapper::HasSubtitles(filename);
} }
UpdateDisplays(true); UpdateDisplays(true, true);
} }
catch (wxString &e) { catch (wxString &e) {
wxMessageBox(e,_T("Error setting video"),wxICON_ERROR | wxOK); wxMessageBox(e,_T("Error setting video"),wxICON_ERROR | wxOK);
} }
} }
loaded = provider != NULL;
} }
/// @brief Add new display /// @brief Add new display
@ -316,10 +316,7 @@ void VideoContext::RemoveDisplay(VideoDisplay *display) {
displayList.remove(display); displayList.remove(display);
} }
/// @brief Update displays void VideoContext::UpdateDisplays(bool full, bool seek) {
/// @param full
///
void VideoContext::UpdateDisplays(bool full) {
if (!loaded) return; if (!loaded) return;
for (std::list<VideoDisplay*>::iterator cur=displayList.begin();cur!=displayList.end();cur++) { for (std::list<VideoDisplay*>::iterator cur=displayList.begin();cur!=displayList.end();cur++) {
@ -329,8 +326,13 @@ void VideoContext::UpdateDisplays(bool full) {
display->UpdateSize(); display->UpdateSize();
display->SetFrameRange(0,GetLength()-1); display->SetFrameRange(0,GetLength()-1);
} }
if (seek) {
display->SetFrame(GetFrameN()); display->SetFrame(GetFrameN());
} }
else {
display->Refresh();
}
}
// Update audio display // Update audio display
if (audio && audio->loaded && audio->IsShownOnScreen()) { if (audio && audio->loaded && audio->IsShownOnScreen()) {
@ -361,17 +363,14 @@ void VideoContext::Refresh () {
/// @return /// @return
/// ///
void VideoContext::JumpToFrame(int n) { void VideoContext::JumpToFrame(int n) {
// Loaded?
if (!loaded) return; if (!loaded) return;
// Prevent intervention during playback // Prevent intervention during playback
if (isPlaying && n != playNextFrame) return; if (isPlaying && n != playNextFrame) return;
// Set frame number
frame_n = n; frame_n = n;
// Display UpdateDisplays(false, true);
UpdateDisplays(false);
// Update grid // Update grid
static agi::OptionValue* highlight = OPT_GET("Subtitle/Grid/Highlight Subtitles in Frame"); static agi::OptionValue* highlight = OPT_GET("Subtitle/Grid/Highlight Subtitles in Frame");

View file

@ -267,7 +267,10 @@ public:
void JumpToTime(int ms,bool exact=false); void JumpToTime(int ms,bool exact=false);
void Refresh(); void Refresh();
void UpdateDisplays(bool full); /// @brief Update the video display
/// @param full Recalculate size and slider lengths
/// @param seek Update is just a seek and file has not changed
void UpdateDisplays(bool full, bool seek = false);
void GetScriptSize(int &w,int &h); void GetScriptSize(int &w,int &h);
wxString GetTempWorkFile (); wxString GetTempWorkFile ();

View file

@ -203,11 +203,12 @@ void VideoDisplay::SetFrame(int frameNumber) {
// Render the new frame // Render the new frame
if (context->IsLoaded()) { if (context->IsLoaded()) {
context->GetScriptSize(scriptW, scriptH); context->GetScriptSize(scriptW, scriptH);
tool->Refresh(); if (!tool.get()) tool.reset(new VisualToolCross(this, video, toolBar));
tool->SetFrame(frameNumber);
AegiVideoFrame frame; AegiVideoFrame frame;
try { try {
frame = context->GetFrame(frameNumber); frame = context->GetFrame(currentFrame);
} }
catch (const wxChar *err) { catch (const wxChar *err) {
wxLogError( wxLogError(
@ -242,6 +243,11 @@ void VideoDisplay::SetFrame(int frameNumber) {
currentFrame = frameNumber; currentFrame = frameNumber;
} }
void VideoDisplay::Refresh() {
tool->Refresh();
Render();
}
void VideoDisplay::SetFrameRange(int from, int to) { void VideoDisplay::SetFrameRange(int from, int to) {
ControlSlider->SetRange(from, to); ControlSlider->SetRange(from, to);
} }
@ -419,7 +425,7 @@ void VideoDisplay::UpdateSize() {
tool->Refresh(); tool->Refresh();
Refresh(false); wxGLCanvas::Refresh(false);
} }
void VideoDisplay::Reset() { void VideoDisplay::Reset() {

View file

@ -148,7 +148,7 @@ class VideoDisplay: public wxGLCanvas {
void OnMode(const wxCommandEvent &event); void OnMode(const wxCommandEvent &event);
void SetMode(int mode); void SetMode(int mode);
/// @brief Switch the active tool to a new object of the specified class /// @brief Switch the active tool to a new object of the specified class
/// @param T The class of the new visual typsetting tool /// @param T The class of the new visual typesetting tool
template <class T> void SetTool(); template <class T> void SetTool();
/// The current script width /// The current script width
@ -189,6 +189,8 @@ public:
/// @from Minimum frame number /// @from Minimum frame number
/// @to Maximum frame number; must be >= from or strange things may happen /// @to Maximum frame number; must be >= from or strange things may happen
void SetFrameRange(int from, int to); void SetFrameRange(int from, int to);
/// @brief Signal that the file has changed
void Refresh();
/// @brief Render the currently visible frame /// @brief Render the currently visible frame
void Render(); void Render();

View file

@ -75,14 +75,13 @@ VisualTool<FeatureType>::VisualTool(VideoDisplay *parent, VideoState const& vide
, dragStartX(0) , dragStartX(0)
, dragStartY(0) , dragStartY(0)
, selChanged(false) , selChanged(false)
, grid(VideoContext::Get()->grid)
, parent(parent) , parent(parent)
, holding(false) , holding(false)
, curDiag(NULL)
, dragging(false) , dragging(false)
, externalChange(true) , externalChange(true)
, curFeature(NULL) , curFeature(NULL)
, dragListOK(false) , dragListOK(false)
, frame_n(0)
, video(video) , video(video)
, leftClick(false) , leftClick(false)
, leftDClick(false) , leftDClick(false)
@ -90,15 +89,14 @@ VisualTool<FeatureType>::VisualTool(VideoDisplay *parent, VideoState const& vide
, ctrlDown(false) , ctrlDown(false)
, altDown(false) , altDown(false)
{ {
frame_n = VideoContext::Get()->GetFrameN(); frameNumber = VideoContext::Get()->GetFrameN();
curDiag = GetActiveDialogueLine();
grid->AddSelectionListener(this); grid->AddSelectionListener(this);
PopulateFeatureList();
} }
template<class FeatureType> template<class FeatureType>
VisualTool<FeatureType>::~VisualTool() { VisualTool<FeatureType>::~VisualTool() {
VideoContext::Get()->grid->RemoveSelectionListener(this); grid->RemoveSelectionListener(this);
} }
template<class FeatureType> template<class FeatureType>
@ -129,6 +127,7 @@ void VisualTool<FeatureType>::OnMouseEvent (wxMouseEvent &event) {
if (!dragListOK) { if (!dragListOK) {
PopulateFeatureList(); PopulateFeatureList();
dragListOK = true; dragListOK = true;
needRender = true;
} }
if (!dragging) { if (!dragging) {
unsigned oldHigh = curFeatureI; unsigned oldHigh = curFeatureI;
@ -159,10 +158,8 @@ void VisualTool<FeatureType>::OnMouseEvent (wxMouseEvent &event) {
if (realTime) { if (realTime) {
Commit(); Commit();
} }
else {
needRender = true; needRender = true;
} }
}
// end drag // end drag
else { else {
if (realTime) AssLimitToVisibleFilter::SetFrame(-1); if (realTime) AssLimitToVisibleFilter::SetFrame(-1);
@ -178,11 +175,8 @@ void VisualTool<FeatureType>::OnMouseEvent (wxMouseEvent &event) {
RemoveSelection(curFeatureI); RemoveSelection(curFeatureI);
} }
else { else {
// deselect everything else SetSelection(curFeatureI);
ClearSelection();
AddSelection(curFeatureI);
} }
SetEditbox();
} }
} }
else { else {
@ -206,10 +200,8 @@ void VisualTool<FeatureType>::OnMouseEvent (wxMouseEvent &event) {
CommitHold(); CommitHold();
Commit(); Commit();
} }
else {
needRender = true; needRender = true;
} }
}
// end hold // end hold
else { else {
if (realTime) AssLimitToVisibleFilter::SetFrame(-1); if (realTime) AssLimitToVisibleFilter::SetFrame(-1);
@ -218,7 +210,6 @@ void VisualTool<FeatureType>::OnMouseEvent (wxMouseEvent &event) {
CommitHold(); CommitHold();
Commit(true); Commit(true);
curDiag = NULL;
parent->ReleaseMouse(); parent->ReleaseMouse();
parent->SetFocus(); parent->SetFocus();
} }
@ -229,15 +220,17 @@ void VisualTool<FeatureType>::OnMouseEvent (wxMouseEvent &event) {
if (InitializeDrag(curFeature)) { if (InitializeDrag(curFeature)) {
if (selFeatures.find(curFeatureI) == selFeatures.end()) { if (selFeatures.find(curFeatureI) == selFeatures.end()) {
selChanged = true; selChanged = true;
if (!ctrlDown) { if (ctrlDown) {
ClearSelection();
}
AddSelection(curFeatureI); AddSelection(curFeatureI);
} }
else {
SetSelection(curFeatureI);
}
}
else { else {
selChanged = false; selChanged = false;
} }
SetEditbox(curFeature->lineN); if (curFeature->line) grid->SetActiveLine(curFeature->line);
dragStartX = video.x; dragStartX = video.x;
dragStartY = video.y; dragStartY = video.y;
@ -248,21 +241,22 @@ void VisualTool<FeatureType>::OnMouseEvent (wxMouseEvent &event) {
dragging = true; dragging = true;
parent->CaptureMouse(); parent->CaptureMouse();
if (realTime) AssLimitToVisibleFilter::SetFrame(frame_n); if (realTime) AssLimitToVisibleFilter::SetFrame(frameNumber);
} }
} }
// start hold // start hold
else { else {
if (!altDown) { if (!altDown) {
ClearSelection(); ClearSelection();
SetEditbox(); Selection sel;
sel.insert(grid->GetActiveLine());
grid->SetSelectedSet(sel);
needRender = true; needRender = true;
} }
curDiag = GetActiveDialogueLine();
if (curDiag && InitializeHold()) { if (curDiag && InitializeHold()) {
holding = true; holding = true;
parent->CaptureMouse(); parent->CaptureMouse();
if (realTime) AssLimitToVisibleFilter::SetFrame(frame_n); if (realTime) AssLimitToVisibleFilter::SetFrame(frameNumber);
} }
} }
} }
@ -273,7 +267,7 @@ void VisualTool<FeatureType>::OnMouseEvent (wxMouseEvent &event) {
template<class FeatureType> template<class FeatureType>
void VisualTool<FeatureType>::Commit(bool full, wxString message) { void VisualTool<FeatureType>::Commit(bool full, wxString message) {
SubtitlesGrid *grid = VideoContext::Get()->grid; externalChange = false;
if (full) { if (full) {
if (message.empty()) { if (message.empty()) {
message = _("visual typesetting"); message = _("visual typesetting");
@ -283,11 +277,11 @@ void VisualTool<FeatureType>::Commit(bool full, wxString message) {
grid->CommitChanges(false,!full); grid->CommitChanges(false,!full);
if (full) if (full)
grid->editBox->Update(false, true); grid->editBox->Update(false, true);
externalChange = true;
} }
template<class FeatureType> template<class FeatureType>
AssDialogue* VisualTool<FeatureType>::GetActiveDialogueLine() { AssDialogue* VisualTool<FeatureType>::GetActiveDialogueLine() {
SubtitlesGrid *grid = VideoContext::Get()->grid;
AssDialogue *diag = grid->GetActiveLine(); AssDialogue *diag = grid->GetActiveLine();
if (grid->IsDisplayed(diag)) if (grid->IsDisplayed(diag))
return diag; return diag;
@ -332,20 +326,61 @@ void VisualTool<FeatureType>::DrawAllFeatures() {
template<class FeatureType> template<class FeatureType>
void VisualTool<FeatureType>::Refresh() { void VisualTool<FeatureType>::Refresh() {
frame_n = VideoContext::Get()->GetFrameN();
if (externalChange) { if (externalChange) {
dragListOK = false; dragListOK = false;
DoRefresh(); curDiag = GetActiveDialogueLine();
OnFileChanged();
} }
} }
template<class FeatureType>
void VisualTool<FeatureType>::SetFrame(int newFrameNumber) {
if (frameNumber == newFrameNumber) return;
OnFrameChanged();
AssDialogue *newCurDiag = GetActiveDialogueLine();
if (newCurDiag != curDiag) {
curDiag = newCurDiag;
OnLineChanged();
}
}
template<class FeatureType>
void VisualTool<FeatureType>::OnActiveLineChanged(AssDialogue *new_line) {
if (new_line && !grid->IsDisplayed(new_line)) {
new_line = NULL;
}
if (new_line != curDiag) {
curDiag = new_line;
OnLineChanged();
}
}
template<class FeatureType>
void VisualTool<FeatureType>::SetSelection(unsigned i) {
assert(i < features.size());
selFeatures.clear();
lineSelCount.clear();
selFeatures.insert(i);
AssDialogue *line = features[i].line;
if (line) {
lineSelCount[line] = 1;
Selection sel;
sel.insert(line);
grid->SetSelectedSet(sel);
}
}
template<class FeatureType> template<class FeatureType>
void VisualTool<FeatureType>::AddSelection(unsigned i) { void VisualTool<FeatureType>::AddSelection(unsigned i) {
assert(i < features.size()); assert(i < features.size());
if (selFeatures.insert(i).second && features[i].line) { if (selFeatures.insert(i).second && features[i].line) {
lineSelCount[features[i].lineN] += 1; lineSelCount[features[i].line] += 1;
SubtitlesGrid *grid = VideoContext::Get()->grid;
grid->SelectRow(features[i].lineN, true); grid->SelectRow(features[i].lineN, true);
} }
} }
@ -357,59 +392,39 @@ void VisualTool<FeatureType>::RemoveSelection(unsigned i) {
if (selFeatures.erase(i) > 0 && features[i].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
int lineN = features[i].lineN; AssDialogue* line = features[i].line;
lineSelCount[lineN] -= 1; lineSelCount[line] -= 1;
assert(lineSelCount[lineN] >= 0); assert(lineSelCount[line] >= 0);
if (lineSelCount[lineN] <= 0) { if (lineSelCount[line] <= 0) {
SubtitlesGrid *grid = VideoContext::Get()->grid; Selection sel = grid->GetSelectedSet();
grid->SelectRow(lineN, true, false);
// We may have just deselected the active line, so make sure the // Don't deselect the only selected line
// edit box is set to something sane if (sel.size() <= 1) return;
SetEditbox();
sel.erase(line);
// Set the active line to an arbitrary selected line if we just
// deselected the active line
if (line == grid->GetActiveLine()) {
grid->SetActiveLine(*sel.begin());
}
grid->SetSelectedSet(sel);
} }
} }
} }
template<class FeatureType> template<class FeatureType>
wxArrayInt VisualTool<FeatureType>::GetSelection() { wxArrayInt VisualTool<FeatureType>::GetSelection() {
return VideoContext::Get()->grid->GetSelection(); return grid->GetSelection();
} }
template<class FeatureType> template<class FeatureType>
void VisualTool<FeatureType>::ClearSelection(bool hard) { void VisualTool<FeatureType>::ClearSelection() {
if (hard) {
Selection sel;
VideoContext::Get()->grid->SetSelectedSet(sel);
}
selFeatures.clear(); selFeatures.clear();
lineSelCount.clear(); lineSelCount.clear();
} }
template<class FeatureType>
void VisualTool<FeatureType>::SetEditbox(int lineN) {
VideoContext* con = VideoContext::Get();
if (lineN > -1) {
con->grid->SetActiveLine(con->grid->GetDialogue(lineN));
con->grid->SelectRow(lineN, true);
}
else {
Selection sel;
con->grid->GetSelectedSet(sel);
// If there is a selection and the edit box's line is in it, do nothing
// Otherwise set the edit box if there is a selection or the selection
// to the edit box if there is no selection
if (sel.empty()) {
sel.insert(con->grid->GetActiveLine());
con->grid->SetSelectedSet(sel);
}
else if (sel.find(con->grid->GetActiveLine()) == sel.end()) {
con->grid->SetActiveLine(con->grid->GetDialogue(con->grid->GetFirstSelRow()));
}
}
}
enum TagFoundType { enum TagFoundType {
TAG_NOT_FOUND = 0, TAG_NOT_FOUND = 0,
PRIMARY_TAG_FOUND, PRIMARY_TAG_FOUND,
@ -461,7 +476,7 @@ void VisualTool<FeatureType>::GetLinePosition(AssDialogue *diag,int &x, int &y,
for (int i=0;i<4;i++) margin[i] = diag->Margin[i]; for (int i=0;i<4;i++) margin[i] = diag->Margin[i];
int align = 2; int align = 2;
AssStyle *style = VideoContext::Get()->grid->ass->GetStyle(diag->Style); AssStyle *style = grid->ass->GetStyle(diag->Style);
if (style) { if (style) {
align = style->alignment; align = style->alignment;
for (int i=0;i<4;i++) { for (int i=0;i<4;i++) {
@ -541,7 +556,7 @@ template<class FeatureType>
void VisualTool<FeatureType>::GetLineRotation(AssDialogue *diag,float &rx,float &ry,float &rz) { void VisualTool<FeatureType>::GetLineRotation(AssDialogue *diag,float &rx,float &ry,float &rz) {
rx = ry = rz = 0.f; rx = ry = rz = 0.f;
AssStyle *style = VideoContext::Get()->grid->ass->GetStyle(diag->Style); AssStyle *style = grid->ass->GetStyle(diag->Style);
if (style) { if (style) {
rz = style->angle; rz = style->angle;
} }
@ -559,7 +574,7 @@ template<class FeatureType>
void VisualTool<FeatureType>::GetLineScale(AssDialogue *diag,float &scalX,float &scalY) { void VisualTool<FeatureType>::GetLineScale(AssDialogue *diag,float &scalX,float &scalY) {
scalX = scalY = 100.f; scalX = scalY = 100.f;
AssStyle *style = VideoContext::Get()->grid->ass->GetStyle(diag->Style); AssStyle *style = grid->ass->GetStyle(diag->Style);
if (style) { if (style) {
scalX = style->scalex; scalX = style->scalex;
scalY = style->scaley; scalY = style->scaley;

View file

@ -50,6 +50,7 @@
class VideoDisplay; class VideoDisplay;
class AssDialogue; class AssDialogue;
class SubtitlesGrid;
struct VideoState; struct VideoState;
namespace agi { namespace agi {
class OptionValue; class OptionValue;
@ -71,6 +72,7 @@ public:
virtual bool Update()=0; virtual bool Update()=0;
virtual void Draw()=0; virtual void Draw()=0;
virtual void Refresh()=0; virtual void Refresh()=0;
virtual void SetFrame(int frame)=0;
virtual ~IVisualTool() { }; virtual ~IVisualTool() { };
}; };
@ -89,25 +91,60 @@ private:
/// or NULL and -1 if there are none /// or NULL and -1 if there are none
void GetHighlightedFeature(); void GetHighlightedFeature();
/// @brief Get the dialogue line currently in the edit box
/// @return NULL if the line is not active on the current frame
AssDialogue *GetActiveDialogueLine();
typedef typename std::set<int>::iterator selection_iterator; typedef typename std::set<int>::iterator selection_iterator;
std::set<int> selFeatures; /// Currently selected visual features std::set<int> selFeatures; /// Currently selected visual features
std::map<int, int> lineSelCount; /// Number of selected features for each line std::map<AssDialogue*, int> lineSelCount; /// Number of selected features for each line
/// @brief Set the edit box's active line, ensuring proper sync with grid
/// @param lineN Line number or -1 for automatic selection
///
/// This function ensures that the selection is not empty and that the line
/// displayed in the edit box is part of the selection, by either setting
/// the edit box to the selection or setting the selection to the edit
/// box's line, as is appropriate.
void SetEditbox(int lineN = -1);
bool selChanged; /// Has the selection already been changed in the current click? bool selChanged; /// Has the selection already been changed in the current click?
/// @brief Called when a hold is begun
/// @return Should the hold actually happen?
virtual bool InitializeHold() { return false; }
/// @brief Called on every mouse event during a hold
virtual void UpdateHold() { }
/// @brief Called at the end of a hold
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
/// @param feature The visual feature clicked on
/// @return Should the drag happen?
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(FeatureType* feature) { }
/// @brief Called at the end of a drag
virtual void CommitDrag(FeatureType* feature) { }
/// Called when the file is changed by something other than a visual tool
virtual void OnFileChanged() { DoRefresh(); }
/// Called when the frame number changes
virtual void OnFrameChanged() { }
/// Called when curDiag changes
virtual void OnLineChanged() { DoRefresh(); }
/// Generic refresh to simplify tools which do the same thing for any
/// external change (i.e. almost all of them). Called only by the above
/// methods.
virtual void DoRefresh() { }
/// @brief Called when there's stuff
/// @return Should the display rerender?
virtual bool Update() { return false; };
/// @brief Draw stuff
virtual void Draw()=0;
protected: protected:
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?
AssDialogue *curDiag; /// Active dialogue line for a hold; only valid when holding = true AssDialogue *curDiag; /// Active dialogue line; NULL if it is not visible on the current frame
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
@ -116,7 +153,7 @@ protected:
std::vector<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? bool dragListOK; /// Do the features not need to be regenerated?
int frame_n; /// Current frame number int frameNumber; /// Current frame number
VideoState const& video; /// Mouse and video information VideoState const& video; /// Mouse and video information
bool leftClick; /// Is a left click event currently being processed? bool leftClick; /// Is a left click event currently being processed?
@ -134,53 +171,27 @@ protected:
wxString GetLineVectorClip(AssDialogue *diag,int &scale,bool &inverse); wxString GetLineVectorClip(AssDialogue *diag,int &scale,bool &inverse);
void SetOverride(AssDialogue* line, wxString tag, wxString value); void SetOverride(AssDialogue* line, wxString tag, wxString value);
/// @brief Get the dialogue line currently in the edit box
/// @return NULL if the line is not active on the current frame
AssDialogue *GetActiveDialogueLine();
/// Draw all of the features in the list /// Draw all of the features in the list
void DrawAllFeatures(); void DrawAllFeatures();
/// @brief Commit the current file state /// @brief Commit the current file state
/// @param message Description of changes for undo /// @param message Description of changes for undo
void Commit(bool full=false, wxString message = L""); void Commit(bool full=false, wxString message = L"");
/// @brief Called when a hold is begun
/// @return Should the hold actually happen?
virtual bool InitializeHold() { return false; }
/// @brief Called on every mouse event during a hold
virtual void UpdateHold() { }
/// @brief Called at the end of a hold
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
/// @param feature The visual feature clicked on
/// @return Should the drag happen?
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(FeatureType* feature) { }
// @brief Called at the end of a drag
virtual void CommitDrag(FeatureType* feature) { }
/// @brief Called by Refresh when there's stuff
virtual void DoRefresh() { }
/// @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(unsigned i);
/// @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(unsigned i);
/// @brief Set the selection to a single feature, deselecting everything else
/// @param i Index in the feature list
void SetSelection(unsigned i);
/// @brief Clear the selection /// @brief Clear the selection
/// @param hard Should the grid's selection be cleared as well? void ClearSelection();
void ClearSelection(bool hard=true);
/// @brief Get the currently selected lines /// @brief Get the currently selected lines
wxArrayInt GetSelection(); wxArrayInt GetSelection();
@ -189,8 +200,7 @@ protected:
protected: protected:
// SubtitleSelectionListener implementation // SubtitleSelectionListener implementation
// (overridden by deriving classes too) void OnActiveLineChanged(AssDialogue *new_line);
virtual 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) { }
public: public:
@ -200,13 +210,13 @@ public:
/// @brief Event handler for the subtoolbar /// @brief Event handler for the subtoolbar
virtual void OnSubTool(wxCommandEvent &) { } virtual void OnSubTool(wxCommandEvent &) { }
/// @brief Called when there's stuff
/// @return Should the display rerender? /// @brief Signal that the file has changed
virtual bool Update() { return false; };
/// @brief Draw stuff
virtual void Draw()=0;
/// @brief Called by stuff when there's stuff, and sometimes when there isn't stuff
void Refresh(); void Refresh();
/// @brief Signal that the current frame number has changed
/// @param newFrameNumber The new frame number
void SetFrame(int newFrameNumber);
/// @brief Constructor /// @brief Constructor
/// @param parent The VideoDisplay to use for coordinate conversion /// @param parent The VideoDisplay to use for coordinate conversion

View file

@ -47,8 +47,6 @@
#include "video_display.h" #include "video_display.h"
#include "visual_tool_clip.h" #include "visual_tool_clip.h"
/// @brief Constructor
/// @param _parent
VisualToolClip::VisualToolClip(VideoDisplay *parent, VideoState const& video, wxToolBar *) VisualToolClip::VisualToolClip(VideoDisplay *parent, VideoState const& video, wxToolBar *)
: VisualTool<ClipCorner>(parent, video) : VisualTool<ClipCorner>(parent, video)
, curX1(0) , curX1(0)
@ -57,14 +55,13 @@ VisualToolClip::VisualToolClip(VideoDisplay *parent, VideoState const& video, wx
, curY2(video.h) , curY2(video.h)
, inverse(false) , inverse(false)
{ {
AssDialogue *line = GetActiveDialogueLine(); if (curDiag) {
if (line) GetLineClip(line,curX1,curY1,curX2,curY2,inverse); GetLineClip(curDiag,curX1,curY1,curX2,curY2,inverse);
}
} }
/// @brief Draw
void VisualToolClip::Draw() { void VisualToolClip::Draw() {
AssDialogue *line = GetActiveDialogueLine(); if (!curDiag) return;
if (!line) return;
int dx1 = curX1; int dx1 = curX1;
int dy1 = curY1; int dy1 = curY1;
@ -95,7 +92,6 @@ void VisualToolClip::Draw() {
DrawAllFeatures(); DrawAllFeatures();
} }
/// @brief Start holding
bool VisualToolClip::InitializeHold() { bool VisualToolClip::InitializeHold() {
startX = video.x; startX = video.x;
startY = video.y; startY = video.y;
@ -104,7 +100,6 @@ bool VisualToolClip::InitializeHold() {
return true; return true;
} }
/// @brief Update hold
void VisualToolClip::UpdateHold() { void VisualToolClip::UpdateHold() {
// Coordinates // Coordinates
curX1 = startX; curX1 = startX;
@ -122,11 +117,9 @@ 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);
// Features
PopulateFeatureList(); PopulateFeatureList();
} }
/// @brief Commit hold
void VisualToolClip::CommitHold() { void VisualToolClip::CommitHold() {
int x1 = curX1; int x1 = curX1;
int x2 = curX2; int x2 = curX2;
@ -134,14 +127,12 @@ void VisualToolClip::CommitHold() {
int y2 = curY2; int y2 = curY2;
parent->ToScriptCoords(&x1, &y1); parent->ToScriptCoords(&x1, &y1);
parent->ToScriptCoords(&x2, &y2); parent->ToScriptCoords(&x2, &y2);
SetOverride(GetActiveDialogueLine(), 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));
} }
/// @brief Populate feature list
void VisualToolClip::PopulateFeatureList() { void VisualToolClip::PopulateFeatureList() {
// Clear
if (features.size() != 4) { if (features.size() != 4) {
ClearSelection(false); ClearSelection();
features.clear(); features.clear();
features.resize(4); features.resize(4);
} }
@ -180,17 +171,12 @@ void VisualToolClip::PopulateFeatureList() {
i++; i++;
} }
/// @brief Initialize
/// @param feature
bool VisualToolClip::InitializeDrag(ClipCorner*) { bool VisualToolClip::InitializeDrag(ClipCorner*) {
curDiag = GetActiveDialogueLine();
curDiag->StripTag(L"\\clip"); curDiag->StripTag(L"\\clip");
curDiag->StripTag(L"\\iclip"); curDiag->StripTag(L"\\iclip");
return true; return true;
} }
/// @brief Update drag
/// @param feature
void VisualToolClip::UpdateDrag(ClipCorner* feature) { void VisualToolClip::UpdateDrag(ClipCorner* feature) {
// Update brothers // Update brothers
feature->horiz->y = feature->y; feature->horiz->y = feature->y;
@ -207,14 +193,20 @@ void VisualToolClip::UpdateDrag(ClipCorner* feature) {
if (curY1 > curY2) std::swap(curY1,curY2); if (curY1 > curY2) std::swap(curY1,curY2);
} }
/// @brief Done dragging
/// @param feature
void VisualToolClip::CommitDrag(ClipCorner*) { void VisualToolClip::CommitDrag(ClipCorner*) {
CommitHold(); CommitHold();
} }
void VisualToolClip::DoRefresh() { void VisualToolClip::OnLineChanged() {
AssDialogue* line = GetActiveDialogueLine(); if (curDiag) {
if (line) GetLineClip(curDiag,curX1,curY1,curX2,curY2,inverse);
GetLineClip(line,curX1,curY1,curX2,curY2,inverse); PopulateFeatureList();
}
}
void VisualToolClip::OnFileChanged() {
if (curDiag) {
GetLineClip(curDiag,curX1,curY1,curX2,curY2,inverse);
PopulateFeatureList();
}
} }

View file

@ -57,43 +57,23 @@ public:
/// ///
/// DOCME /// DOCME
class VisualToolClip : public VisualTool<ClipCorner> { class VisualToolClip : public VisualTool<ClipCorner> {
private:
/// DOCME
/// DOCME
/// DOCME
/// DOCME
/// DOCME
/// DOCME
int startX,startY,curX1,curY1,curX2,curY2; int startX,startY,curX1,curY1,curX2,curY2;
/// DOCME
bool inverse; bool inverse;
/// @brief DOCME
/// @return
///
bool InitializeHold(); bool InitializeHold();
void UpdateHold(); void UpdateHold();
void CommitHold(); void CommitHold();
void OnLineChanged();
void OnFileChanged();
/// @brief DOCME
///
void PopulateFeatureList(); void PopulateFeatureList();
bool InitializeDrag(ClipCorner* feature); bool InitializeDrag(ClipCorner* feature);
void UpdateDrag(ClipCorner* feature); void UpdateDrag(ClipCorner* feature);
void CommitDrag(ClipCorner* feature); void CommitDrag(ClipCorner* feature);
void DoRefresh(); void Draw();
public: public:
VisualToolClip(VideoDisplay *parent, VideoState const& video, wxToolBar *); VisualToolClip(VideoDisplay *parent, VideoState const& video, wxToolBar *);
void Draw();
}; };

View file

@ -43,26 +43,19 @@
#include "video_display.h" #include "video_display.h"
#include "visual_tool_cross.h" #include "visual_tool_cross.h"
/// @brief Constructor
/// @param _parent
VisualToolCross::VisualToolCross(VideoDisplay *parent, VideoState const& video, wxToolBar *) VisualToolCross::VisualToolCross(VideoDisplay *parent, VideoState const& video, wxToolBar *)
: VisualTool<VisualDraggableFeature>(parent, video) : VisualTool<VisualDraggableFeature>(parent, video)
{ {
} }
VisualToolCross::~VisualToolCross() { }
/// @brief Update
bool VisualToolCross::Update() { bool VisualToolCross::Update() {
if (!leftDClick) return true; if (!leftDClick) return true;
if (!curDiag) return true;
AssDialogue* line = GetActiveDialogueLine();
if (!line) return true;
int dx, dy; int dx, dy;
int vx = video.x; int vx = video.x;
int vy = video.y; int vy = video.y;
GetLinePosition(line, dx, dy); GetLinePosition(curDiag, dx, dy);
parent->ToScriptCoords(&vx, &vy); parent->ToScriptCoords(&vx, &vy);
parent->ToScriptCoords(&dx, &dy); parent->ToScriptCoords(&dx, &dy);
dx -= vx; dx -= vx;
@ -71,7 +64,7 @@ bool VisualToolCross::Update() {
SubtitlesGrid *grid = VideoContext::Get()->grid; SubtitlesGrid *grid = VideoContext::Get()->grid;
wxArrayInt sel = grid->GetSelection(); wxArrayInt sel = grid->GetSelection();
for (wxArrayInt::const_iterator cur = sel.begin(); cur != sel.end(); ++cur) { for (wxArrayInt::const_iterator cur = sel.begin(); cur != sel.end(); ++cur) {
line = grid->GetDialogue(*cur); AssDialogue *line = grid->GetDialogue(*cur);
if (!line) continue; if (!line) continue;
int x1, y1; int x1, y1;
GetLinePosition(line, x1, y1); GetLinePosition(line, x1, y1);
@ -83,7 +76,6 @@ bool VisualToolCross::Update() {
return false; return false;
} }
/// @brief Draw
void VisualToolCross::Draw() { void VisualToolCross::Draw() {
// Draw cross // Draw cross
glDisable(GL_LINE_SMOOTH); glDisable(GL_LINE_SMOOTH);

View file

@ -44,12 +44,8 @@
/// ///
/// DOCME /// DOCME
class VisualToolCross : public VisualTool<VisualDraggableFeature> { class VisualToolCross : public VisualTool<VisualDraggableFeature> {
public:
VisualToolCross(VideoDisplay *parent, VideoState const& video, wxToolBar *);
~VisualToolCross();
bool Update(); bool Update();
void Draw(); void Draw();
public:
VisualToolCross(VideoDisplay *parent, VideoState const& video, wxToolBar *);
}; };

View file

@ -70,11 +70,10 @@ VisualToolDrag::VisualToolDrag(VideoDisplay *parent, VideoState const& video, wx
void VisualToolDrag::UpdateToggleButtons() { void VisualToolDrag::UpdateToggleButtons() {
// Check which bitmap to use // Check which bitmap to use
bool toMove = true; bool toMove = true;
AssDialogue *line = GetActiveDialogueLine(); if (curDiag) {
if (line) {
int x1,y1,x2,y2,t1,t2; int x1,y1,x2,y2,t1,t2;
bool hasMove; bool hasMove;
GetLineMove(line,hasMove,x1,y1,x2,y2,t1,t2); GetLineMove(curDiag,hasMove,x1,y1,x2,y2,t1,t2);
toMove = !hasMove; toMove = !hasMove;
} }
@ -117,13 +116,24 @@ void VisualToolDrag::OnSubTool(wxCommandEvent &) {
Refresh(); Refresh();
} }
void VisualToolDrag::DoRefresh() { void VisualToolDrag::OnLineChanged() {
UpdateToggleButtons(); UpdateToggleButtons();
} }
void VisualToolDrag::OnFileChanged() {
/// @todo be less dumb and preserve selections when possible
PopulateFeatureList();
}
void VisualToolDrag::OnFrameChanged() {
/// @todo be less dumb and preserve selections when possible
PopulateFeatureList();
}
void VisualToolDrag::OnSelectedSetChanged(const Selection &added, const Selection &removed) { void VisualToolDrag::OnSelectedSetChanged(const Selection &added, const Selection &removed) {
if (!externalChange) return; if (!externalChange) return;
externalChange = false; externalChange = false;
grid->BeginBatch();
// Remove all deselected lines // Remove all deselected lines
for (size_t i = 0; i < features.size(); i++) { for (size_t i = 0; i < features.size(); i++) {
@ -139,6 +149,7 @@ void VisualToolDrag::OnSelectedSetChanged(const Selection &added, const Selectio
} }
} }
grid->EndBatch();
externalChange = true; externalChange = true;
} }
@ -193,7 +204,7 @@ void VisualToolDrag::Draw() {
} }
void VisualToolDrag::PopulateFeatureList() { void VisualToolDrag::PopulateFeatureList() {
ClearSelection(false); ClearSelection();
primary = -1; primary = -1;
GenerateFeatures(); GenerateFeatures();
} }
@ -267,7 +278,7 @@ bool VisualToolDrag::InitializeDrag(VisualToolDragDraggableFeature *feature) {
/// @param feature /// @param feature
void VisualToolDrag::UpdateDrag(VisualToolDragDraggableFeature* feature) { void VisualToolDrag::UpdateDrag(VisualToolDragDraggableFeature* feature) {
// Update "time" to reflect the time of the frame in which the feature is being dragged // Update "time" to reflect the time of the frame in which the feature is being dragged
int time = VFR_Output.GetTimeAtFrame(frame_n,true,true); 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()); feature->time = MID(0,time - feature->line->Start.GetMS(),feature->line->End.GetMS()-feature->line->Start.GetMS());
} }
@ -317,9 +328,8 @@ bool VisualToolDrag::Update() {
dy = features[primary].y; dy = features[primary].y;
} }
else { else {
AssDialogue* line = GetActiveDialogueLine(); if (!curDiag) return false;
if (!line) return false; GetLinePosition(curDiag, dx, dy);
GetLinePosition(line, dx, dy);
} }
parent->ToScriptCoords(&dx, &dy); parent->ToScriptCoords(&dx, &dy);
dx -= vx; dx -= vx;

View file

@ -80,16 +80,18 @@ private:
/// 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();
void DoRefresh();
protected:
// Overriding SubtitleSelectionListener inherited from base VisualTool<> // Overriding SubtitleSelectionListener inherited from base VisualTool<>
virtual void OnSelectedSetChanged(const Selection &lines_added, const Selection &lines_removed); void OnSelectedSetChanged(const Selection &lines_added, const Selection &lines_removed);
public: void OnFrameChanged();
VisualToolDrag(VideoDisplay *parent, VideoState const& video, wxToolBar *toolbar); void OnFileChanged();
void OnLineChanged();
void Draw(); void Draw();
bool Update(); bool Update();
public:
VisualToolDrag(VideoDisplay *parent, VideoState const& video, wxToolBar *toolbar);
void OnSubTool(wxCommandEvent &event); void OnSubTool(wxCommandEvent &event);
}; };

View file

@ -48,35 +48,22 @@
#include "video_display.h" #include "video_display.h"
#include "visual_tool_rotatexy.h" #include "visual_tool_rotatexy.h"
/// @brief Constructor
/// @param _parent
VisualToolRotateXY::VisualToolRotateXY(VideoDisplay *parent, VideoState const& video, wxToolBar *) VisualToolRotateXY::VisualToolRotateXY(VideoDisplay *parent, VideoState const& video, wxToolBar *)
: VisualTool<VisualDraggableFeature>(parent, video) : VisualTool<VisualDraggableFeature>(parent, video)
{ {
DoRefresh(); DoRefresh();
} }
/// @brief Draw
void VisualToolRotateXY::Draw() { void VisualToolRotateXY::Draw() {
AssDialogue *line = GetActiveDialogueLine(); if (!curDiag) return;
if (!line) return;
// Pivot coordinates // Pivot coordinates
int dx=0,dy=0; int dx=0,dy=0;
if (dragging) GetLinePosition(line,dx,dy); if (dragging) GetLinePosition(curDiag,dx,dy);
else GetLinePosition(line,dx,dy,orgx,orgy); else GetLinePosition(curDiag,dx,dy,orgx,orgy);
dx = orgx; dx = orgx;
dy = orgy; dy = orgy;
// Rotation
float rx,ry;
GetLineRotation(line,rx,ry,rz);
if (line == curDiag) {
rx = curAngleX;
ry = curAngleY;
}
// Set colours
SetLineColour(colour[0]); SetLineColour(colour[0]);
SetFillColour(colour[1],0.3f); SetFillColour(colour[1],0.3f);
@ -87,98 +74,92 @@ void VisualToolRotateXY::Draw() {
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glPushMatrix(); glPushMatrix();
glLoadIdentity(); glLoadIdentity();
glTranslatef(dx,dy,0.0f); glTranslatef(dx,dy,0.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.0f,1.0f,8.0f); glScalef(1.f,1.f,8.f);
if (ry != 0.0f) glRotatef(ry,0.0f,-1.0f,0.0f); if (curAngleY != 0.f) glRotatef(curAngleY,0.f,-1.f,0.f);
if (rx != 0.0f) glRotatef(rx,-1.0f,0.0f,0.0f); if (curAngleX != 0.f) glRotatef(curAngleX,-1.f,0.f,0.f);
if (rz != 0.0f) glRotatef(rz,0.0f,0.0f,-1.0f); if (curAngleZ != 0.f) glRotatef(curAngleZ,0.f,0.f,-1.f);
// Draw grid // Draw grid
glShadeModel(GL_SMOOTH); glShadeModel(GL_SMOOTH);
SetLineColour(colour[0],0.5f,2); SetLineColour(colour[0],0.5f,2);
SetModeLine(); SetModeLine();
float r = colour[0].Red()/255.0f; float r = colour[0].Red()/255.f;
float g = colour[0].Green()/255.0f; float g = colour[0].Green()/255.f;
float b = colour[0].Blue()/255.0f; float b = colour[0].Blue()/255.f;
glBegin(GL_LINES); glBegin(GL_LINES);
for (int i=0;i<11;i++) { for (int i=0;i<11;i++) {
float a = 1.0f - abs(i-5)*0.18f; float a = 1.f - abs(i-5)*0.18f;
int pos = 20*(i-5); int pos = 20*(i-5);
glColor4f(r,g,b,0.0f); glColor4f(r,g,b,0.f);
glVertex2i(pos,120); glVertex2i(pos,120);
glColor4f(r,g,b,a); glColor4f(r,g,b,a);
glVertex2i(pos,0); glVertex2i(pos,0);
glVertex2i(pos,0); glVertex2i(pos,0);
glColor4f(r,g,b,0.0f); glColor4f(r,g,b,0.f);
glVertex2i(pos,-120); glVertex2i(pos,-120);
glVertex2i(120,pos); glVertex2i(120,pos);
glColor4f(r,g,b,a); glColor4f(r,g,b,a);
glVertex2i(0,pos); glVertex2i(0,pos);
glVertex2i(0,pos); glVertex2i(0,pos);
glColor4f(r,g,b,0.0f); glColor4f(r,g,b,0.f);
glVertex2i(-120,pos); glVertex2i(-120,pos);
} }
glEnd(); glEnd();
// Draw vectors // Draw vectors
SetLineColour(colour[3],1.0f,2); SetLineColour(colour[3],1.f,2);
SetModeLine(); SetModeLine();
glBegin(GL_LINES); glBegin(GL_LINES);
glVertex3f(0.0f,0.0f,0.0f); glVertex3f(0.f,0.f,0.f);
glVertex3f(50.0f,0.0f,0.0f); glVertex3f(50.f,0.f,0.f);
glVertex3f(0.0f,0.0f,0.0f); glVertex3f(0.f,0.f,0.f);
glVertex3f(0.0f,50.0f,0.0f); glVertex3f(0.f,50.f,0.f);
glVertex3f(0.0f,0.0f,0.0f); glVertex3f(0.f,0.f,0.f);
glVertex3f(0.0f,0.0f,50.0f); glVertex3f(0.f,0.f,50.f);
glEnd(); glEnd();
// Draw arrow tops // Draw arrow tops
glBegin(GL_TRIANGLE_FAN); glBegin(GL_TRIANGLE_FAN);
glVertex3f(60.0f,0.0f,0.0f); glVertex3f(60.f,0.f,0.f);
glVertex3f(50.0f,-3.0f,-3.0f); glVertex3f(50.f,-3.f,-3.f);
glVertex3f(50.0f,3.0f,-3.0f); glVertex3f(50.f,3.f,-3.f);
glVertex3f(50.0f,3.0f,3.0f); glVertex3f(50.f,3.f,3.f);
glVertex3f(50.0f,-3.0f,3.0f); glVertex3f(50.f,-3.f,3.f);
glVertex3f(50.0f,-3.0f,-3.0f); glVertex3f(50.f,-3.f,-3.f);
glEnd(); glEnd();
glBegin(GL_TRIANGLE_FAN); glBegin(GL_TRIANGLE_FAN);
glVertex3f(0.0f,60.0f,0.0f); glVertex3f(0.f,60.f,0.f);
glVertex3f(-3.0f,50.0f,-3.0f); glVertex3f(-3.f,50.f,-3.f);
glVertex3f(3.0f,50.0f,-3.0f); glVertex3f(3.f,50.f,-3.f);
glVertex3f(3.0f,50.0f,3.0f); glVertex3f(3.f,50.f,3.f);
glVertex3f(-3.0f,50.0f,3.0f); glVertex3f(-3.f,50.f,3.f);
glVertex3f(-3.0f,50.0f,-3.0f); glVertex3f(-3.f,50.f,-3.f);
glEnd(); glEnd();
glBegin(GL_TRIANGLE_FAN); glBegin(GL_TRIANGLE_FAN);
glVertex3f(0.0f,0.0f,60.0f); glVertex3f(0.f,0.f,60.f);
glVertex3f(-3.0f,-3.0f,50.0f); glVertex3f(-3.f,-3.f,50.f);
glVertex3f(3.0f,-3.0f,50.0f); glVertex3f(3.f,-3.f,50.f);
glVertex3f(3.0f,3.0f,50.0f); glVertex3f(3.f,3.f,50.f);
glVertex3f(-3.0f,3.0f,50.0f); glVertex3f(-3.f,3.f,50.f);
glVertex3f(-3.0f,-3.0f,50.0f); glVertex3f(-3.f,-3.f,50.f);
glEnd(); glEnd();
// Restore gl's state
glPopMatrix(); glPopMatrix();
glShadeModel(GL_FLAT); glShadeModel(GL_FLAT);
} }
/// @brief Start holding
bool VisualToolRotateXY::InitializeHold() { bool VisualToolRotateXY::InitializeHold() {
if (!curDiag) return false;
GetLinePosition(curDiag,odx,ody,orgx,orgy);
GetLineRotation(curDiag,origAngleX,origAngleY,rz);
startAngleX = (orgy-video.y)*2.f; startAngleX = (orgy-video.y)*2.f;
startAngleY = (video.x-orgx)*2.f; startAngleY = (video.x-orgx)*2.f;
curAngleX = origAngleX; origAngleX = curAngleX;
curAngleY = origAngleY; origAngleY = curAngleY;
return true; return true;
} }
/// @brief Update hold
void VisualToolRotateXY::UpdateHold() { void VisualToolRotateXY::UpdateHold() {
float screenAngleX = (orgy-video.y)*2.f; float screenAngleX = (orgy-video.y)*2.f;
float screenAngleY = (video.x-orgx)*2.f; float screenAngleY = (video.x-orgx)*2.f;
@ -204,9 +185,7 @@ void VisualToolRotateXY::UpdateHold() {
} }
} }
/// @brief Commit hold
void VisualToolRotateXY::CommitHold() { void VisualToolRotateXY::CommitHold() {
SubtitlesGrid *grid = VideoContext::Get()->grid;
wxArrayInt sel = grid->GetSelection(); wxArrayInt sel = grid->GetSelection();
for (wxArrayInt::const_iterator cur = sel.begin(); cur != sel.end(); ++cur) { for (wxArrayInt::const_iterator cur = sel.begin(); cur != sel.end(); ++cur) {
AssDialogue* line = grid->GetDialogue(*cur); AssDialogue* line = grid->GetDialogue(*cur);
@ -216,11 +195,11 @@ void VisualToolRotateXY::CommitHold() {
} }
} }
/// @brief Get \\org pivot
void VisualToolRotateXY::PopulateFeatureList() { void VisualToolRotateXY::PopulateFeatureList() {
curDiag = GetActiveDialogueLine();
if (!curDiag) return; if (!curDiag) return;
GetLinePosition(curDiag,odx,ody,orgx,orgy);
int posx, posy;
GetLinePosition(curDiag,posx,posy,orgx,orgy);
// Set features // Set features
features.resize(1); features.resize(1);
@ -231,15 +210,11 @@ void VisualToolRotateXY::PopulateFeatureList() {
feat.type = DRAG_BIG_TRIANGLE; feat.type = DRAG_BIG_TRIANGLE;
} }
/// @brief Update dragging of \\org
/// @param feature
void VisualToolRotateXY::UpdateDrag(VisualDraggableFeature* feature) { void VisualToolRotateXY::UpdateDrag(VisualDraggableFeature* feature) {
orgx = feature->x; orgx = feature->x;
orgy = feature->y; orgy = feature->y;
} }
/// @brief Commit dragging of \\org
/// @param feature
void VisualToolRotateXY::CommitDrag(VisualDraggableFeature* feature) { void VisualToolRotateXY::CommitDrag(VisualDraggableFeature* feature) {
int x = feature->x; int x = feature->x;
int y = feature->y; int y = feature->y;
@ -247,11 +222,9 @@ void VisualToolRotateXY::CommitDrag(VisualDraggableFeature* feature) {
SetOverride(feature->line, L"\\org",wxString::Format(L"(%i,%i)",x,y)); SetOverride(feature->line, L"\\org",wxString::Format(L"(%i,%i)",x,y));
} }
/// @brief Refresh
void VisualToolRotateXY::DoRefresh() { void VisualToolRotateXY::DoRefresh() {
AssDialogue *line = GetActiveDialogueLine(); if (!curDiag) return;
if (!line) return; int posx, posy;
GetLinePosition(line,odx,ody,orgx,orgy); GetLinePosition(curDiag,posx,posy,orgx,orgy);
GetLineRotation(line,curAngleX,curAngleY,rz); GetLineRotation(curDiag,curAngleX,curAngleY,curAngleZ);
} }

View file

@ -41,53 +41,23 @@
/// @class VisualToolRotateXY /// @class VisualToolRotateXY
/// @brief DOCME /// @brief DOCME
class VisualToolRotateXY : public VisualTool<VisualDraggableFeature> { class VisualToolRotateXY : public VisualTool<VisualDraggableFeature> {
private:
/// DOCME
/// DOCME
/// DOCME
float curAngleX,startAngleX,origAngleX; float curAngleX,startAngleX,origAngleX;
/// DOCME
/// DOCME
/// DOCME
float curAngleY,startAngleY,origAngleY; float curAngleY,startAngleY,origAngleY;
float curAngleZ;
int orgx,orgy;
/// DOCME
/// DOCME
/// DOCME
/// DOCME
int orgx,orgy,odx,ody;
/// DOCME
float rz;
/// @brief DOCME
/// @return
///
bool InitializeHold(); bool InitializeHold();
void UpdateHold(); void UpdateHold();
void CommitHold(); void CommitHold();
/// @brief DOCME
///
void PopulateFeatureList(); void PopulateFeatureList();
void UpdateDrag(VisualDraggableFeature* feature); void UpdateDrag(VisualDraggableFeature* feature);
void CommitDrag(VisualDraggableFeature* feature); void CommitDrag(VisualDraggableFeature* feature);
void DoRefresh(); void DoRefresh();
void Draw();
public: public:
VisualToolRotateXY(VideoDisplay *parent, VideoState const& video, wxToolBar *); VisualToolRotateXY(VideoDisplay *parent, VideoState const& video, wxToolBar *);
void Draw();
}; };

View file

@ -36,7 +36,7 @@
#include "config.h" #include "config.h"
#ifndef AGI_PRE #ifndef AGI_PRE
#include <math.h> #include <cmath>
#endif #endif
#include "ass_dialogue.h" #include "ass_dialogue.h"
@ -48,50 +48,27 @@
#include "video_display.h" #include "video_display.h"
#include "visual_tool_rotatez.h" #include "visual_tool_rotatez.h"
/// @brief Constructor static const float deg2rad = 3.1415926536f / 180.f;
/// @param _parent 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)
{ {
DoRefresh(); DoRefresh();
} }
/// @brief Draw
void VisualToolRotateZ::Draw() { void VisualToolRotateZ::Draw() {
// Get line to draw if (!curDiag) return;
AssDialogue *line = GetActiveDialogueLine();
if (!line) return;
// Draw pivot // Draw pivot
DrawAllFeatures(); DrawAllFeatures();
// Radius int radius = (int)sqrt(double((posx-orgx)*(posx-orgx)+(posy-orgy)*(posy-orgy)));
int dx=0,dy=0;
if (dragging) GetLinePosition(line,dx,dy);
else GetLinePosition(line,dx,dy,orgx,orgy);
int radius = (int) sqrt(double((dx-orgx)*(dx-orgx)+(dy-orgy)*(dy-orgy)));
int oRadius = radius; int oRadius = radius;
if (radius < 50) radius = 50; if (radius < 50) radius = 50;
// Pivot coordinates int deltax = int(cos(curAngle*deg2rad)*radius);
int odx = dx; int deltay = int(-sin(curAngle*deg2rad)*radius);
int ody = dy;
dx = orgx;
dy = orgy;
// Rotation
float rz;
GetLineRotation(line,rx,ry,rz);
if (line == curDiag) rz = curAngle;
// Get scale
float scalX = 100.0f;
float scalY = 100.0f;
GetLineScale(line,scalX,scalY);
// Get deltas
int deltax = int(cos(rz*3.1415926536/180.0)*radius);
int deltay = int(-sin(rz*3.1415926536/180.0)*radius);
// Set colours // Set colours
SetLineColour(colour[0]); SetLineColour(colour[0]);
@ -101,84 +78,76 @@ void VisualToolRotateZ::Draw() {
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glPushMatrix(); glPushMatrix();
glLoadIdentity(); glLoadIdentity();
glTranslatef(dx,dy,-1.0f); glTranslatef(orgx,orgy,-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.0f,1.0f,8.0f); glScalef(1.f,1.f,8.f);
glRotatef(ry,0.0f,-1.0f,0.0f); glRotatef(ry,0.f,-1.f,0.f);
glRotatef(rx,-1.0f,0.0f,0.0f); glRotatef(rx,-1.f,0.f,0.f);
glScalef(scalX/100.0f,scalY/100.0f,1.0f); glScalef(scaleX/100.f,scaleY/100.f,1.f);
// Draw the circle // Draw the circle
DrawRing(0,0,radius+4,radius-4); DrawRing(0,0,radius+4,radius-4);
// Draw markers around circle // Draw markers around circle
int markers = 6; int markers = 6;
float markStart = -90.0f / markers; float markStart = -90.f / markers;
float markEnd = markStart+(180.0f/markers); float markEnd = markStart+(180.f/markers);
for (int i=0;i<markers;i++) { for (int i=0;i<markers;i++) {
float angle = i*(360.0f/markers); float angle = i*(360.f/markers);
DrawRing(0,0,radius+30,radius+12,radius/radius,angle+markStart,angle+markEnd); DrawRing(0,0,radius+30,radius+12,radius/radius,angle+markStart,angle+markEnd);
} }
// Draw the baseline // Draw the baseline
SetLineColour(colour[3],1.0f,2); SetLineColour(colour[3],1.f,2);
DrawLine(deltax,deltay,-deltax,-deltay); DrawLine(deltax,deltay,-deltax,-deltay);
// Draw the connection line // Draw the connection line
if (orgx != odx && orgy != ody) { if (orgx != posx || orgy != posy) {
double angle = atan2(double(dy-ody),double(odx-dx)) + rz*3.1415926536/180.0; double angle = atan2(double(orgy-posy),double(posx-orgx)) + 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);
int mdx = int(cos(rz*3.1415926536/180.0)*20); int mdx = int(cos(curAngle*deg2rad)*20);
int mdy = int(-sin(rz*3.1415926536/180.0)*20); int mdy = int(-sin(curAngle*deg2rad)*20);
DrawLine(fx-mdx,fy-mdy,fx+mdx,fy+mdy); DrawLine(fx-mdx,fy-mdy,fx+mdx,fy+mdy);
} }
// Draw the rotation line // Draw the rotation line
SetLineColour(colour[0],1.0f,1); SetLineColour(colour[0],1.f,1);
SetFillColour(colour[1],0.3f); SetFillColour(colour[1],0.3f);
DrawCircle(deltax,deltay,4); DrawCircle(deltax,deltay,4);
// Restore
glPopMatrix(); glPopMatrix();
// Draw line to mouse // Draw line to mouse
if (!dragging && !curFeature && video.x > INT_MIN && video.y > INT_MIN) { if (!dragging && !curFeature && video.x > INT_MIN && video.y > INT_MIN) {
SetLineColour(colour[0]); SetLineColour(colour[0]);
DrawLine(dx,dy,video.x,video.y); DrawLine(orgx,orgy,video.x,video.y);
} }
} }
/// @brief Start holding
bool VisualToolRotateZ::InitializeHold() { bool VisualToolRotateZ::InitializeHold() {
GetLinePosition(curDiag,odx,ody,orgx,orgy); startAngle = atan2(double(orgy-video.y),double(video.x-orgx)) * rad2deg;
startAngle = atan2(double(orgy-video.y),double(video.x-orgx)) * 180.0 / 3.1415926535897932; origAngle = curAngle;
GetLineRotation(curDiag,rx,ry,origAngle);
curAngle = origAngle;
curDiag->StripTag(L"\\frz"); curDiag->StripTag(L"\\frz");
curDiag->StripTag(L"\\fr"); curDiag->StripTag(L"\\fr");
return true; return true;
} }
/// @brief Update hold
void VisualToolRotateZ::UpdateHold() { void VisualToolRotateZ::UpdateHold() {
// Find angle float screenAngle = atan2(double(orgy-video.y),double(video.x-orgx)) * rad2deg;
float screenAngle = atan2(double(orgy-video.y),double(video.x-orgx)) * 180.0 / 3.1415926535897932;
curAngle = fmodf(screenAngle - startAngle + origAngle + 360.f, 360.f); curAngle = fmodf(screenAngle - startAngle + origAngle + 360.f, 360.f);
// Oh Snap // Oh Snap
if (ctrlDown) { if (ctrlDown) {
curAngle = floorf(curAngle/30.f+.5f)*30.0f; curAngle = floorf(curAngle/30.f+.5f)*30.f;
if (curAngle > 359.0f) curAngle = 0.0f; if (curAngle > 359.f) curAngle = 0.f;
} }
} }
/// @brief Commit hold
void VisualToolRotateZ::CommitHold() { void VisualToolRotateZ::CommitHold() {
SubtitlesGrid *grid = VideoContext::Get()->grid;
wxArrayInt sel = grid->GetSelection(); wxArrayInt sel = grid->GetSelection();
for (wxArrayInt::const_iterator cur = sel.begin(); cur != sel.end(); ++cur) { for (wxArrayInt::const_iterator cur = sel.begin(); cur != sel.end(); ++cur) {
AssDialogue* line = grid->GetDialogue(*cur); AssDialogue* line = grid->GetDialogue(*cur);
@ -187,11 +156,8 @@ void VisualToolRotateZ::CommitHold() {
} }
} }
/// @brief Get \\org pivot
void VisualToolRotateZ::PopulateFeatureList() { void VisualToolRotateZ::PopulateFeatureList() {
curDiag = GetActiveDialogueLine();
if (!curDiag) return; if (!curDiag) return;
GetLinePosition(curDiag,odx,ody,orgx,orgy);
// Set features // Set features
features.resize(1); features.resize(1);
@ -202,15 +168,11 @@ void VisualToolRotateZ::PopulateFeatureList() {
feat.type = DRAG_BIG_TRIANGLE; feat.type = DRAG_BIG_TRIANGLE;
} }
/// @brief Update dragging of \\org
/// @param feature
void VisualToolRotateZ::UpdateDrag(VisualDraggableFeature* feature) { void VisualToolRotateZ::UpdateDrag(VisualDraggableFeature* feature) {
orgx = feature->x; orgx = feature->x;
orgy = feature->y; orgy = feature->y;
} }
/// @brief Commit dragging of \\org
/// @param feature
void VisualToolRotateZ::CommitDrag(VisualDraggableFeature* feature) { void VisualToolRotateZ::CommitDrag(VisualDraggableFeature* feature) {
int x = feature->x; int x = feature->x;
int y = feature->y; int y = feature->y;
@ -218,10 +180,9 @@ void VisualToolRotateZ::CommitDrag(VisualDraggableFeature* feature) {
SetOverride(feature->line, L"\\org",wxString::Format(L"(%i,%i)",x,y)); SetOverride(feature->line, L"\\org",wxString::Format(L"(%i,%i)",x,y));
} }
/// @brief Refresh
void VisualToolRotateZ::DoRefresh() { void VisualToolRotateZ::DoRefresh() {
AssDialogue *line = GetActiveDialogueLine(); if (!curDiag) return;
if (!line) return; GetLinePosition(curDiag, posx, posy, orgx, orgy);
GetLinePosition(line,odx,ody,orgx,orgy); GetLineRotation(curDiag, rx, ry, curAngle);
GetLineRotation(line,rx,ry,curAngle); GetLineScale(curDiag, scaleX, scaleY);
} }

View file

@ -44,49 +44,24 @@
/// ///
/// DOCME /// DOCME
class VisualToolRotateZ : public VisualTool<VisualDraggableFeature> { class VisualToolRotateZ : public VisualTool<VisualDraggableFeature> {
private:
/// DOCME
/// DOCME
/// DOCME
float curAngle, startAngle, origAngle; float curAngle, startAngle, origAngle;
int orgx, orgy;
/// DOCME int posx, posy;
/// DOCME
/// DOCME
/// DOCME
int orgx,orgy,odx,ody;
/// DOCME
/// DOCME
float rx, ry; float rx, ry;
float scaleX, scaleY;
/// @brief DOCME
/// @return
///
bool InitializeHold(); bool InitializeHold();
void UpdateHold(); void UpdateHold();
void CommitHold(); void CommitHold();
/// @brief DOCME
///
void PopulateFeatureList(); void PopulateFeatureList();
void UpdateDrag(VisualDraggableFeature* feature); void UpdateDrag(VisualDraggableFeature* feature);
void CommitDrag(VisualDraggableFeature* feature); void CommitDrag(VisualDraggableFeature* feature);
void DoRefresh(); void DoRefresh();
public:
VisualToolRotateZ(VideoDisplay *parent, VideoState const& video, wxToolBar *);
void Draw(); void Draw();
bool Update() { return true; } bool Update() { return true; }
public:
VisualToolRotateZ(VideoDisplay *parent, VideoState const& video, wxToolBar *);
}; };

View file

@ -48,42 +48,25 @@
#include "video_display.h" #include "video_display.h"
#include "visual_tool_scale.h" #include "visual_tool_scale.h"
/// @brief Constructor
/// @param _parent
VisualToolScale::VisualToolScale(VideoDisplay *parent, VideoState const& video, wxToolBar *) VisualToolScale::VisualToolScale(VideoDisplay *parent, VideoState const& video, wxToolBar *)
: VisualTool<VisualDraggableFeature>(parent, video) : VisualTool<VisualDraggableFeature>(parent, video)
, curScaleX(0.f) , curScaleX(0.f)
, startScaleX(0.f)
, origScaleX(0.f) , origScaleX(0.f)
, curScaleY(0.f) , curScaleY(0.f)
, startScaleY(0.f)
, origScaleY(0.f) , origScaleY(0.f)
, startX(0) , startX(0)
, startY(0) , startY(0)
{ {
DoRefresh();
} }
/// @brief Draw
void VisualToolScale::Draw() { void VisualToolScale::Draw() {
// Get line to draw if (!curDiag) return;
AssDialogue *line = GetActiveDialogueLine();
if (!line) return;
// Get scale
if (line != curDiag) GetLineScale(line,curScaleX,curScaleY);
// Get line position and rotation
int dx,dy;
float rx,ry,rz;
GetLinePosition(line,dx,dy);
GetLineRotation(line,rx,ry,rz);
// Set dx/dy
int len = 160; int len = 160;
dx = MID(len/2+10,dx,video.w-len/2-30); int dx = MID(len/2+10,posx,video.w-len/2-30);
dy = MID(len/2+10,dy,video.h-len/2-30); int dy = MID(len/2+10,posy,video.h-len/2-30);
// Set colours
SetLineColour(colour[0]); SetLineColour(colour[0]);
SetFillColour(colour[1],0.3f); SetFillColour(colour[1],0.3f);
@ -91,13 +74,13 @@ void VisualToolScale::Draw() {
glMatrixMode(GL_MODELVIEW); glMatrixMode(GL_MODELVIEW);
glPushMatrix(); glPushMatrix();
glLoadIdentity(); glLoadIdentity();
glTranslatef(dx,dy,0.0f); glTranslatef(dx,dy,0.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.0f,1.0f,8.0f); glScalef(1.f,1.f,8.f);
if (ry != 0.0f) glRotatef(ry,0.0f,-1.0f,0.0f); if (ry != 0.f) glRotatef(ry,0.f,-1.f,0.f);
if (rx != 0.0f) glRotatef(rx,-1.0f,0.0f,0.0f); if (rx != 0.f) glRotatef(rx,-1.f,0.f,0.f);
if (rz != 0.0f) glRotatef(rz,0.0f,0.0f,-1.0f); if (rz != 0.f) glRotatef(rz,0.f,0.f,-1.f);
// Scale parameters // Scale parameters
int lenx = int(1.6 * curScaleX); int lenx = int(1.6 * curScaleX);
@ -106,46 +89,42 @@ void VisualToolScale::Draw() {
int drawY = len/2 + 10; int drawY = len/2 + 10;
// Draw length markers // Draw length markers
SetLineColour(colour[3],1.0f,2); SetLineColour(colour[3],1.f,2);
DrawLine(-lenx/2,drawY+10,lenx/2,drawY+10); DrawLine(-lenx/2,drawY+10,lenx/2,drawY+10);
DrawLine(drawX+10,-leny/2,drawX+10,leny/2); DrawLine(drawX+10,-leny/2,drawX+10,leny/2);
SetLineColour(colour[0],1.0f,1); SetLineColour(colour[0],1.f,1);
SetFillColour(colour[1],0.3f); SetFillColour(colour[1],0.3f);
DrawCircle(lenx/2,drawY+10,4); DrawCircle(lenx/2,drawY+10,4);
DrawCircle(drawX+10,-leny/2,4); DrawCircle(drawX+10,-leny/2,4);
// Draw horizontal scale // Draw horizontal scale
SetLineColour(colour[0],1.0f,1); SetLineColour(colour[0],1.f,1);
DrawRectangle(-len/2,drawY,len/2+1,drawY+5); DrawRectangle(-len/2,drawY,len/2+1,drawY+5);
SetLineColour(colour[0],1.0f,2); SetLineColour(colour[0],1.f,2);
DrawLine(-len/2+1,drawY+5,-len/2+1,drawY+15); DrawLine(-len/2+1,drawY+5,-len/2+1,drawY+15);
DrawLine(len/2,drawY+5,len/2,drawY+15); DrawLine(len/2,drawY+5,len/2,drawY+15);
// Draw vertical scale // Draw vertical scale
SetLineColour(colour[0],1.0f,1); SetLineColour(colour[0],1.f,1);
DrawRectangle(drawX,-len/2,drawX+5,len/2+1); DrawRectangle(drawX,-len/2,drawX+5,len/2+1);
SetLineColour(colour[0],1.0f,2); SetLineColour(colour[0],1.f,2);
DrawLine(drawX+5,-len/2+1,drawX+15,-len/2+1); DrawLine(drawX+5,-len/2+1,drawX+15,-len/2+1);
DrawLine(drawX+5,len/2,drawX+15,len/2); DrawLine(drawX+5,len/2,drawX+15,len/2);
// Restore gl's state
glPopMatrix(); glPopMatrix();
} }
/// @brief Start holding
bool VisualToolScale::InitializeHold() { bool VisualToolScale::InitializeHold() {
startX = video.x; startX = video.x;
startY = video.y; startY = video.y;
GetLineScale(curDiag,origScaleX,origScaleY); origScaleX = curScaleX;
curScaleX = origScaleX; origScaleY = curScaleY;
curScaleY = origScaleY;
curDiag->StripTag(L"\\fscx"); curDiag->StripTag(L"\\fscx");
curDiag->StripTag(L"\\fscy"); curDiag->StripTag(L"\\fscy");
return true; return true;
} }
/// @brief Update hold
void VisualToolScale::UpdateHold() { void VisualToolScale::UpdateHold() {
using std::max; using std::max;
// Deltas // Deltas
@ -162,14 +141,12 @@ void VisualToolScale::UpdateHold() {
// Oh Snap // Oh Snap
if (ctrlDown) { if (ctrlDown) {
curScaleX = floorf(curScaleX/25.f+.5f)*25.0f; curScaleX = floorf(curScaleX/25.f+.5f)*25.f;
curScaleY = floorf(curScaleY/25.f+.5f)*25.0f; curScaleY = floorf(curScaleY/25.f+.5f)*25.f;
} }
} }
/// @brief Commit hold
void VisualToolScale::CommitHold() { void VisualToolScale::CommitHold() {
SubtitlesGrid *grid = VideoContext::Get()->grid;
wxArrayInt sel = grid->GetSelection(); wxArrayInt sel = grid->GetSelection();
for (wxArrayInt::const_iterator cur = sel.begin(); cur != sel.end(); ++cur) { for (wxArrayInt::const_iterator cur = sel.begin(); cur != sel.end(); ++cur) {
AssDialogue* line = grid->GetDialogue(*cur); AssDialogue* line = grid->GetDialogue(*cur);
@ -178,3 +155,11 @@ void VisualToolScale::CommitHold() {
SetOverride(line, L"\\fscy",wxString::Format(L"(%0.3g)",curScaleY)); SetOverride(line, L"\\fscy",wxString::Format(L"(%0.3g)",curScaleY));
} }
} }
void VisualToolScale::DoRefresh() {
if (!curDiag) return;
GetLineScale(curDiag, curScaleX, curScaleY);
GetLinePosition(curDiag, posx, posy);
GetLineRotation(curDiag, rx, ry, rz);
}

View file

@ -41,36 +41,20 @@
/// @class VisualToolScale /// @class VisualToolScale
/// @brief DOCME /// @brief DOCME
class VisualToolScale : public VisualTool<VisualDraggableFeature> { class VisualToolScale : public VisualTool<VisualDraggableFeature> {
private: float curScaleX, origScaleX;
float curScaleY, origScaleY;
/// DOCME
/// DOCME
/// DOCME
float curScaleX,startScaleX,origScaleX;
/// DOCME
/// DOCME
/// DOCME
float curScaleY,startScaleY,origScaleY;
/// DOCME
/// DOCME
int startX, startY; int startX, startY;
int posx, posy;
float rx, ry, rz;
/// @brief DOCME
///
bool InitializeHold(); bool InitializeHold();
void UpdateHold(); void UpdateHold();
void CommitHold(); void CommitHold();
void DoRefresh();
void Draw();
public: public:
VisualToolScale(VideoDisplay *parent, VideoState const& video, wxToolBar *); VisualToolScale(VideoDisplay *parent, VideoState const& video, wxToolBar *);
void Draw();
}; };

View file

@ -56,6 +56,7 @@
#include "video_display.h" #include "video_display.h"
#include "visual_tool_vector_clip.h" #include "visual_tool_vector_clip.h"
/// Button IDs
enum { enum {
BUTTON_DRAG = VISUAL_SUB_TOOL_START, BUTTON_DRAG = VISUAL_SUB_TOOL_START,
BUTTON_LINE, BUTTON_LINE,
@ -68,17 +69,11 @@ 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
}; };
/// @brief Constructor
/// @param parent
/// @param _toolBar
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)
{ {
DoRefresh();
mode = 0;
// Create 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);
@ -94,9 +89,8 @@ VisualToolVectorClip::VisualToolVectorClip(VideoDisplay *parent, VideoState cons
toolBar->Realize(); toolBar->Realize();
toolBar->Show(true); toolBar->Show(true);
// Set default mode DoRefresh();
PopulateFeatureList(); SetMode(features.empty());
if (features.size() == 0) SetMode(1);
} }
void VisualToolVectorClip::OnSubTool(wxCommandEvent &event) { void VisualToolVectorClip::OnSubTool(wxCommandEvent &event) {
@ -124,13 +118,11 @@ static bool is_move(SplineCurve const& c) {
} }
void VisualToolVectorClip::Draw() { void VisualToolVectorClip::Draw() {
if (!curDiag) return;
if (spline.empty()) return; if (spline.empty()) return;
GL_EXT(PFNGLMULTIDRAWARRAYSPROC, glMultiDrawArrays); GL_EXT(PFNGLMULTIDRAWARRAYSPROC, glMultiDrawArrays);
AssDialogue *line = GetActiveDialogueLine();
if (!line) return;
// Parse vector // Parse vector
std::vector<float> points; std::vector<float> points;
std::vector<int> start; std::vector<int> start;
@ -170,7 +162,7 @@ void VisualToolVectorClip::Draw() {
// Draw the actual rectangle // Draw the actual rectangle
glColorMask(1,1,1,1); glColorMask(1,1,1,1);
SetLineColour(colour[3],0.0f); SetLineColour(colour[3],0.f);
SetFillColour(wxColour(0,0,0),0.5f); SetFillColour(wxColour(0,0,0),0.5f);
// VSFilter draws when the winding number is nonzero, so we want to draw the // VSFilter draws when the winding number is nonzero, so we want to draw the
@ -181,8 +173,8 @@ void VisualToolVectorClip::Draw() {
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);
// Draw lines // Draw lines
SetFillColour(colour[3],0.0f); SetFillColour(colour[3],0.f);
SetLineColour(colour[3],1.0f,2); SetLineColour(colour[3],1.f,2);
SetModeLine(); SetModeLine();
glMultiDrawArrays(GL_LINE_LOOP, &start[0], &count[0], start.size()); glMultiDrawArrays(GL_LINE_LOOP, &start[0], &count[0], start.size());
@ -272,7 +264,6 @@ void VisualToolVectorClip::MakeFeature(Spline::iterator cur) {
} }
} }
/// @brief Populate feature list
void VisualToolVectorClip::PopulateFeatureList() { void VisualToolVectorClip::PopulateFeatureList() {
features.clear(); features.clear();
// This is perhaps a bit conservative as there can be up to 3N+1 features // This is perhaps a bit conservative as there can be up to 3N+1 features
@ -283,21 +274,14 @@ void VisualToolVectorClip::PopulateFeatureList() {
} }
} }
/// @brief Update
/// @param feature
void VisualToolVectorClip::UpdateDrag(VisualToolVectorClipDraggableFeature* feature) { void VisualToolVectorClip::UpdateDrag(VisualToolVectorClipDraggableFeature* feature) {
spline.MovePoint(feature->curve,feature->point,Vector2D(feature->x,feature->y)); spline.MovePoint(feature->curve,feature->point,Vector2D(feature->x,feature->y));
} }
/// @brief Commit void VisualToolVectorClip::CommitDrag(VisualToolVectorClipDraggableFeature*) {
/// @param feature SetOverride(curDiag, inverse ? L"\\iclip" : L"\\clip", L"(" + spline.EncodeToASS() + L")");
void VisualToolVectorClip::CommitDrag(VisualToolVectorClipDraggableFeature* feature) {
SetOverride(GetActiveDialogueLine(), inverse ? L"\\iclip" : L"\\clip", L"(" + spline.EncodeToASS() + L")");
} }
/// @brief Clicked a feature
/// @param feature
/// @return
bool VisualToolVectorClip::InitializeDrag(VisualToolVectorClipDraggableFeature* feature) { bool VisualToolVectorClip::InitializeDrag(VisualToolVectorClipDraggableFeature* feature) {
// Delete a control point // Delete a control point
if (mode == 5) { if (mode == 5) {
@ -319,15 +303,13 @@ bool VisualToolVectorClip::InitializeDrag(VisualToolVectorClipDraggableFeature*
CommitDrag(feature); CommitDrag(feature);
curFeature = NULL; curFeature = NULL;
PopulateFeatureList(); PopulateFeatureList();
ClearSelection(false); ClearSelection();
Commit(true); Commit(true);
return false; return false;
} }
return true; return true;
} }
/// @brief Initialize hold
/// @return
bool VisualToolVectorClip::InitializeHold() { bool VisualToolVectorClip::InitializeHold() {
// Insert line/bicubic // Insert line/bicubic
if (mode == 1 || mode == 2) { if (mode == 1 || mode == 2) {
@ -348,7 +330,7 @@ bool VisualToolVectorClip::InitializeHold() {
// Insert // Insert
spline.push_back(curve); spline.push_back(curve);
ClearSelection(false); ClearSelection();
MakeFeature(--spline.end()); MakeFeature(--spline.end());
UpdateHold(); UpdateHold();
return true; return true;
@ -401,7 +383,7 @@ bool VisualToolVectorClip::InitializeHold() {
} }
// Commit // Commit
SetOverride(GetActiveDialogueLine(), inverse ? L"\\iclip" : L"\\clip", L"(" + spline.EncodeToASS() + L")"); SetOverride(curDiag, inverse ? L"\\iclip" : L"\\clip", L"(" + spline.EncodeToASS() + L")");
Commit(true); Commit(true);
DoRefresh(); DoRefresh();
return false; return false;
@ -409,7 +391,7 @@ bool VisualToolVectorClip::InitializeHold() {
// Freehand // Freehand
if (mode == 6 || mode == 7) { if (mode == 6 || mode == 7) {
ClearSelection(false); ClearSelection();
features.clear(); features.clear();
spline.clear(); spline.clear();
SplineCurve curve; SplineCurve curve;
@ -422,7 +404,6 @@ bool VisualToolVectorClip::InitializeHold() {
return false; return false;
} }
/// @brief Update hold
void VisualToolVectorClip::UpdateHold() { void VisualToolVectorClip::UpdateHold() {
// Insert line // Insert line
if (mode == 1) { if (mode == 1) {
@ -470,7 +451,6 @@ void VisualToolVectorClip::UpdateHold() {
} }
} }
/// @brief Commit hold
void VisualToolVectorClip::CommitHold() { void VisualToolVectorClip::CommitHold() {
// Smooth spline // Smooth spline
if (!holding && mode == 7) { if (!holding && mode == 7) {
@ -490,25 +470,19 @@ void VisualToolVectorClip::CommitHold() {
} }
} }
/// @brief Refresh
void VisualToolVectorClip::DoRefresh() { void VisualToolVectorClip::DoRefresh() {
if (!dragging && !holding) { if (!curDiag) return;
// Get line
AssDialogue *line = GetActiveDialogueLine();
if (!line) return;
// Get clip vector
wxString vect; wxString vect;
int scale; int scale;
vect = GetLineVectorClip(line,scale,inverse); vect = GetLineVectorClip(curDiag,scale,inverse);
spline.DecodeFromASS(vect); spline.DecodeFromASS(vect);
SelectAll(); SelectAll();
PopulateFeatureList(); PopulateFeatureList();
} }
}
void VisualToolVectorClip::SelectAll() { void VisualToolVectorClip::SelectAll() {
ClearSelection(false); ClearSelection();
for (size_t i = 0; i < features.size(); ++i) { for (size_t i = 0; i < features.size(); ++i) {
AddSelection(i); AddSelection(i);
} }

View file

@ -82,12 +82,11 @@ class VisualToolVectorClip : public VisualTool<VisualToolVectorClipDraggableFeat
bool InitializeDrag(VisualToolVectorClipDraggableFeature* feature); bool InitializeDrag(VisualToolVectorClipDraggableFeature* feature);
void DoRefresh(); void DoRefresh();
void Draw();
bool Update() { return mode >= 1 && mode <= 4; }
public: public:
VisualToolVectorClip(VideoDisplay *parent, VideoState const& video, wxToolBar *toolbar); VisualToolVectorClip(VideoDisplay *parent, VideoState const& video, wxToolBar *toolbar);
void Draw();
bool Update() { return mode >= 1 && mode <= 4; }
/// Subtoolbar button click handler /// Subtoolbar button click handler
void OnSubTool(wxCommandEvent &event); void OnSubTool(wxCommandEvent &event);
}; };