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

View file

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

View file

@ -148,7 +148,7 @@ class VideoDisplay: public wxGLCanvas {
void OnMode(const wxCommandEvent &event);
void SetMode(int mode);
/// @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();
/// The current script width
@ -189,6 +189,8 @@ public:
/// @from Minimum frame number
/// @to Maximum frame number; must be >= from or strange things may happen
void SetFrameRange(int from, int to);
/// @brief Signal that the file has changed
void Refresh();
/// @brief Render the currently visible frame
void Render();

View file

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

View file

@ -50,6 +50,7 @@
class VideoDisplay;
class AssDialogue;
class SubtitlesGrid;
struct VideoState;
namespace agi {
class OptionValue;
@ -71,6 +72,7 @@ public:
virtual bool Update()=0;
virtual void Draw()=0;
virtual void Refresh()=0;
virtual void SetFrame(int frame)=0;
virtual ~IVisualTool() { };
};
@ -89,25 +91,60 @@ private:
/// or NULL and -1 if there are none
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;
std::set<int> selFeatures; /// Currently selected visual features
std::map<int, 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);
std::map<AssDialogue*, int> lineSelCount; /// Number of selected features for each line
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:
SubtitlesGrid *grid;
VideoDisplay *parent; /// VideoDisplay which this belongs to, used to frame conversion
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 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
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
bool leftClick; /// Is a left click event currently being processed?
@ -134,53 +171,27 @@ protected:
wxString GetLineVectorClip(AssDialogue *diag,int &scale,bool &inverse);
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
void DrawAllFeatures();
/// @brief Commit the current file state
/// @param message Description of changes for undo
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
/// @param i Index in the feature list
void AddSelection(unsigned i);
/// @brief Remove a feature from the selection
/// @param i Index in the feature list
/// Also deselects lines if all features for that line have been deselected
void RemoveSelection(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
/// @param hard Should the grid's selection be cleared as well?
void ClearSelection(bool hard=true);
void ClearSelection();
/// @brief Get the currently selected lines
wxArrayInt GetSelection();
@ -189,8 +200,7 @@ protected:
protected:
// SubtitleSelectionListener implementation
// (overridden by deriving classes too)
virtual void OnActiveLineChanged(AssDialogue *new_line) { }
void OnActiveLineChanged(AssDialogue *new_line);
virtual void OnSelectedSetChanged(const Selection &lines_added, const Selection &lines_removed) { }
public:
@ -200,13 +210,13 @@ public:
/// @brief Event handler for the subtoolbar
virtual void OnSubTool(wxCommandEvent &) { }
/// @brief Called when there's stuff
/// @return Should the display rerender?
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
/// @brief Signal that the file has changed
void Refresh();
/// @brief Signal that the current frame number has changed
/// @param newFrameNumber The new frame number
void SetFrame(int newFrameNumber);
/// @brief Constructor
/// @param parent The VideoDisplay to use for coordinate conversion

View file

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

View file

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

View file

@ -44,12 +44,8 @@
///
/// DOCME
class VisualToolCross : public VisualTool<VisualDraggableFeature> {
public:
VisualToolCross(VideoDisplay *parent, VideoState const& video, wxToolBar *);
~VisualToolCross();
bool Update();
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() {
// Check which bitmap to use
bool toMove = true;
AssDialogue *line = GetActiveDialogueLine();
if (line) {
if (curDiag) {
int x1,y1,x2,y2,t1,t2;
bool hasMove;
GetLineMove(line,hasMove,x1,y1,x2,y2,t1,t2);
GetLineMove(curDiag,hasMove,x1,y1,x2,y2,t1,t2);
toMove = !hasMove;
}
@ -117,13 +116,24 @@ void VisualToolDrag::OnSubTool(wxCommandEvent &) {
Refresh();
}
void VisualToolDrag::DoRefresh() {
void VisualToolDrag::OnLineChanged() {
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) {
if (!externalChange) return;
externalChange = false;
grid->BeginBatch();
// Remove all deselected lines
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;
}
@ -193,7 +204,7 @@ void VisualToolDrag::Draw() {
}
void VisualToolDrag::PopulateFeatureList() {
ClearSelection(false);
ClearSelection();
primary = -1;
GenerateFeatures();
}
@ -267,7 +278,7 @@ bool VisualToolDrag::InitializeDrag(VisualToolDragDraggableFeature *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(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());
}
@ -317,9 +328,8 @@ bool VisualToolDrag::Update() {
dy = features[primary].y;
}
else {
AssDialogue* line = GetActiveDialogueLine();
if (!line) return false;
GetLinePosition(line, dx, dy);
if (!curDiag) return false;
GetLinePosition(curDiag, dx, dy);
}
parent->ToScriptCoords(&dx, &dy);
dx -= vx;

View file

@ -80,16 +80,18 @@ private:
/// Set the pos/move button to the correct icon based on the active line
void UpdateToggleButtons();
void DoRefresh();
protected:
// 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:
VisualToolDrag(VideoDisplay *parent, VideoState const& video, wxToolBar *toolbar);
void OnFrameChanged();
void OnFileChanged();
void OnLineChanged();
void Draw();
bool Update();
public:
VisualToolDrag(VideoDisplay *parent, VideoState const& video, wxToolBar *toolbar);
void OnSubTool(wxCommandEvent &event);
};

View file

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

View file

@ -41,53 +41,23 @@
/// @class VisualToolRotateXY
/// @brief DOCME
class VisualToolRotateXY : public VisualTool<VisualDraggableFeature> {
private:
/// DOCME
/// DOCME
/// DOCME
float curAngleX,startAngleX,origAngleX;
/// DOCME
/// DOCME
/// DOCME
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();
void UpdateHold();
void CommitHold();
/// @brief DOCME
///
void PopulateFeatureList();
void UpdateDrag(VisualDraggableFeature* feature);
void CommitDrag(VisualDraggableFeature* feature);
void DoRefresh();
void Draw();
public:
VisualToolRotateXY(VideoDisplay *parent, VideoState const& video, wxToolBar *);
void Draw();
};

View file

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

View file

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

View file

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

View file

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

View file

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