Make visual tools use only screen coordinates.

Previously the visual typesetting tools and the overlay mask used
several coordinate frames, converting between them in many places in
inconsistent ways.  This elimiates all uses of coordinate frames other
than screen and script, and makes the conversion done in one place, and
only when parsing or serializing ASS.

This fixes:

 - A few minor rounding errors

 - Horrible brokeness when only part of the video frame is being
   displayed, due to higher levels of zoom than fit onscreen or panning
   the video

 - Distortion of the visual typesetting tools when the combination of
   overridden aspect ratio, script resolution, and video resolution did
   not result in square pixels.

 - Resolution-dependence of the visual typesetting tools, which resulted
   in some tools becoming hard to use at zooms outside the range of
   100-200%.

 - Some draggable controls used the mouse's script coordinates,
   resulting in noticable jerky movement at high zoom levels or when
   using strange script resolutions.

Closes #966.

Originally committed to SVN as r4289.
This commit is contained in:
Thomas Goyne 2010-05-16 06:39:11 +00:00
parent 74a9bdeb41
commit 2c876e79c3
25 changed files with 569 additions and 833 deletions

View File

@ -34,9 +34,6 @@
/// @ingroup visual_ts /// @ingroup visual_ts
/// ///
///////////
// Headers
#include "config.h" #include "config.h"
#ifndef AGI_PRE #ifndef AGI_PRE
@ -45,18 +42,14 @@
#include "spline.h" #include "spline.h"
#include "utils.h" #include "utils.h"
#include "video_display.h"
/// @brief Spline constructor /// @brief Spline constructor
/// Spline::Spline(const VideoDisplay &scale) : scale(scale) {
Spline::Spline() {
} }
/// @brief Encode to ASS /// @brief Encode to ASS
/// @return
///
wxString Spline::EncodeToASS() { wxString Spline::EncodeToASS() {
wxString result; wxString result;
char lastCommand = 0; char lastCommand = 0;
@ -68,38 +61,52 @@ wxString Spline::EncodeToASS() {
for (std::list<SplineCurve>::iterator cur=curves.begin();cur!=curves.end();cur++) { for (std::list<SplineCurve>::iterator cur=curves.begin();cur!=curves.end();cur++) {
// Start of spline // Start of spline
if (isFirst) { if (isFirst) {
result = wxString::Format(_T("m %i %i "),(int)cur->p1.x,(int)cur->p1.y); int x = cur->p1.x;
int y = cur->p1.y;
scale.ToScriptCoords(&x, &y);
result = wxString::Format(L"m %i %i ", x, y);
lastCommand = 'm'; lastCommand = 'm';
isFirst = false; isFirst = false;
} }
// Each curve // Each curve
switch (cur->type) { switch (cur->type) {
case CURVE_LINE: case CURVE_LINE: {
if (lastCommand != 'l') { if (lastCommand != 'l') {
result += _T("l "); result += L"l ";
lastCommand = 'l'; lastCommand = 'l';
} }
result += wxString::Format(_T("%i %i "),(int)cur->p2.x,(int)cur->p2.y); int x = cur->p2.x;
int y = cur->p2.y;
scale.ToScriptCoords(&x, &y);
result += wxString::Format(L"%i %i ", x, y);
break; break;
case CURVE_BICUBIC: }
case CURVE_BICUBIC: {
if (lastCommand != 'b') { if (lastCommand != 'b') {
result += _T("b "); result += L"b ";
lastCommand = 'b'; lastCommand = 'b';
} }
result += wxString::Format(_T("%i %i %i %i %i %i "),(int)cur->p2.x,(int)cur->p2.y,(int)cur->p3.x,(int)cur->p3.y,(int)cur->p4.x,(int)cur->p4.y); int x2 = cur->p2.x;
int y2 = cur->p2.y;
int x3 = cur->p3.x;
int y3 = cur->p3.y;
int x4 = cur->p4.x;
int y4 = cur->p4.y;
scale.ToScriptCoords(&x2, &y2);
scale.ToScriptCoords(&x3, &y3);
scale.ToScriptCoords(&x4, &y4);
result += wxString::Format(L"%i %i %i %i %i %i ", x2, y2, x3, y3, x4, y4);
break; break;
}
default: break; default: break;
} }
} }
return result; return result;
} }
/// @brief Decode from ASS /// @brief Decode from ASS
/// @param str /// @param str
///
void Spline::DecodeFromASS(wxString str) { void Spline::DecodeFromASS(wxString str) {
// Clear current // Clear current
curves.clear(); curves.clear();
@ -112,7 +119,7 @@ void Spline::DecodeFromASS(wxString str) {
bool coordsSet = false; bool coordsSet = false;
// Tokenize the string // Tokenize the string
wxStringTokenizer tkn(str,_T(" ")); wxStringTokenizer tkn(str,L" ");
while (tkn.HasMoreTokens()) { while (tkn.HasMoreTokens()) {
wxString token = tkn.GetNextToken(); wxString token = tkn.GetNextToken();
@ -126,26 +133,31 @@ void Spline::DecodeFromASS(wxString str) {
if (stack.size() == 2 && lastCommand == 'm') { if (stack.size() == 2 && lastCommand == 'm') {
x = stack[0]; x = stack[0];
y = stack[1]; y = stack[1];
scale.FromScriptCoords(&x, &y);
coordsSet = true; coordsSet = true;
stack.clear(); stack.clear();
} }
// Line // Line
if (stack.size() == 2 && lastCommand == 'l') { if (stack.size() == 2 && lastCommand == 'l') {
scale.FromScriptCoords(&stack[0], &stack[1]);
SplineCurve curve; SplineCurve curve;
curve.p1.x = x; curve.p1.x = x;
curve.p1.y = y; curve.p1.y = y;
curve.p2.x = stack[0]; curve.p2.x = stack[0];
curve.p2.y = stack[1]; curve.p2.y = stack[1];
curve.type = CURVE_LINE; curve.type = CURVE_LINE;
x = (int)curve.p2.x; x = curve.p2.x;
y = (int)curve.p2.y; y = curve.p2.y;
stack.clear(); stack.clear();
AppendCurve(curve); AppendCurve(curve);
} }
// Bicubic // Bicubic
else if (stack.size() == 6 && lastCommand == 'b') { else if (stack.size() == 6 && lastCommand == 'b') {
scale.FromScriptCoords(&stack[0], &stack[1]);
scale.FromScriptCoords(&stack[2], &stack[3]);
scale.FromScriptCoords(&stack[4], &stack[5]);
SplineCurve curve; SplineCurve curve;
curve.p1.x = x; curve.p1.x = x;
curve.p1.y = y; curve.p1.y = y;
@ -156,8 +168,8 @@ void Spline::DecodeFromASS(wxString str) {
curve.p4.x = stack[4]; curve.p4.x = stack[4];
curve.p4.y = stack[5]; curve.p4.y = stack[5];
curve.type = CURVE_BICUBIC; curve.type = CURVE_BICUBIC;
x = (int)curve.p4.x; x = curve.p4.x;
y = (int)curve.p4.y; y = curve.p4.y;
stack.clear(); stack.clear();
AppendCurve(curve); AppendCurve(curve);
} }
@ -170,12 +182,12 @@ void Spline::DecodeFromASS(wxString str) {
// Got something else // Got something else
else { else {
if (token == _T("m")) lastCommand = 'm'; if (token == L"m") lastCommand = 'm';
else if (token == _T("l")) lastCommand = 'l'; else if (token == L"l") lastCommand = 'l';
else if (token == _T("b")) lastCommand = 'b'; else if (token == L"b") lastCommand = 'b';
else if (token == _T("n")) lastCommand = 'n'; else if (token == L"n") lastCommand = 'n';
else if (token == _T("s")) lastCommand = 's'; else if (token == L"s") lastCommand = 's';
else if (token == _T("c")) lastCommand = 'c'; else if (token == L"c") lastCommand = 'c';
} }
} }
@ -189,12 +201,9 @@ void Spline::DecodeFromASS(wxString str) {
} }
} }
/// @brief Insert a curve to the spline /// @brief Insert a curve to the spline
/// @param curve /// @param curve
/// @param index /// @param index
///
void Spline::InsertCurve(SplineCurve &curve,int index) { void Spline::InsertCurve(SplineCurve &curve,int index) {
if (index == -1) curves.push_back(curve); if (index == -1) curves.push_back(curve);
else { else {
@ -205,12 +214,9 @@ void Spline::InsertCurve(SplineCurve &curve,int index) {
} }
} }
/// @brief Get a specific curve /// @brief Get a specific curve
/// @param index /// @param index
/// @return /// @return
///
SplineCurve *Spline::GetCurve(int index) { SplineCurve *Spline::GetCurve(int index) {
int i=0; int i=0;
for (std::list<SplineCurve>::iterator cur=curves.begin();cur!=curves.end() && i <= index;cur++,i++) { for (std::list<SplineCurve>::iterator cur=curves.begin();cur!=curves.end() && i <= index;cur++,i++) {
@ -219,13 +225,10 @@ SplineCurve *Spline::GetCurve(int index) {
return NULL; return NULL;
} }
/// @brief Moves a specific point in the spline /// @brief Moves a specific point in the spline
/// @param curveIndex /// @param curveIndex
/// @param point /// @param point
/// @param pos /// @param pos
///
void Spline::MovePoint(int curveIndex,int point,wxPoint pos) { void Spline::MovePoint(int curveIndex,int point,wxPoint pos) {
// Curves // Curves
int i = 0; int i = 0;
@ -234,12 +237,9 @@ void Spline::MovePoint(int curveIndex,int point,wxPoint pos) {
SplineCurve *c2 = NULL; SplineCurve *c2 = NULL;
// Indices // Indices
//int size = curves.size();
int i0 = curveIndex-1; int i0 = curveIndex-1;
int i1 = curveIndex; int i1 = curveIndex;
int i2 = curveIndex+1; int i2 = curveIndex+1;
//if (i0 < 0) i0 = size-1;
//if (i2 >= size) i2 = 0;
// Get the curves // Get the curves
for (std::list<SplineCurve>::iterator cur = curves.begin();cur!=curves.end();cur++) { for (std::list<SplineCurve>::iterator cur = curves.begin();cur!=curves.end();cur++) {
@ -286,12 +286,9 @@ void Spline::MovePoint(int curveIndex,int point,wxPoint pos) {
} }
} }
/// @brief Gets a list of points in the curve /// @brief Gets a list of points in the curve
/// @param points /// @param points
/// @param pointCurve /// @param pointCurve
///
void Spline::GetPointList(std::vector<Vector2D> &points,std::vector<int> &pointCurve) { void Spline::GetPointList(std::vector<Vector2D> &points,std::vector<int> &pointCurve) {
// Prepare // Prepare
points.clear(); points.clear();
@ -343,15 +340,11 @@ void Spline::GetPointList(std::vector<Vector2D> &points,std::vector<int> &pointC
} }
} }
/// @brief t value and curve of the point closest to reference /// @brief t value and curve of the point closest to reference
/// @param reference /// @param reference
/// @param curve /// @param curve
/// @param t /// @param t
/// @param pt /// @param pt
/// @return
///
void Spline::GetClosestParametricPoint(Vector2D reference,int &curve,float &t,Vector2D &pt) { void Spline::GetClosestParametricPoint(Vector2D reference,int &curve,float &t,Vector2D &pt) {
// Has at least one curve? // Has at least one curve?
curve = -1; curve = -1;
@ -384,12 +377,9 @@ void Spline::GetClosestParametricPoint(Vector2D reference,int &curve,float &t,Ve
curves.pop_back(); curves.pop_back();
} }
/// @brief Point closest to reference /// @brief Point closest to reference
/// @param reference /// @param reference
/// @return /// @return
///
Vector2D Spline::GetClosestPoint(Vector2D reference) { Vector2D Spline::GetClosestPoint(Vector2D reference) {
int curve; int curve;
float t; float t;
@ -409,11 +399,8 @@ Vector2D Spline::GetClosestControlPoint(Vector2D reference) {
return Vector2D(-1,-1); return Vector2D(-1,-1);
} }
/// @brief Smoothes the spline /// @brief Smoothes the spline
/// @param smooth /// @param smooth
///
void Spline::Smooth(float smooth) { void Spline::Smooth(float smooth) {
// See if there are enough curves // See if there are enough curves
if (curves.size() < 3) return; if (curves.size() < 3) return;
@ -434,5 +421,3 @@ void Spline::Smooth(float smooth) {
curve1->Smooth(curve0->p1,curve2->p2,smooth); curve1->Smooth(curve0->p1,curve2->p2,smooth);
} }
} }

View File

@ -34,11 +34,6 @@
/// @ingroup visual_ts /// @ingroup visual_ts
/// ///
///////////
// Headers
#ifndef AGI_PRE #ifndef AGI_PRE
#include <list> #include <list>
#include <vector> #include <vector>
@ -48,19 +43,21 @@
#include "spline_curve.h" #include "spline_curve.h"
class VideoDisplay;
/// DOCME /// DOCME
/// @class Spline /// @class Spline
/// @brief DOCME /// @brief DOCME
///
/// DOCME
class Spline { class Spline {
private:
const VideoDisplay &scale;
public: public:
/// DOCME /// DOCME
std::list<SplineCurve> curves; std::list<SplineCurve> curves;
Spline(); Spline(const VideoDisplay &scale);
wxString EncodeToASS(); wxString EncodeToASS();
void DecodeFromASS(wxString str); void DecodeFromASS(wxString str);
@ -81,5 +78,3 @@ public:
Vector2D GetClosestPoint(Vector2D reference); Vector2D GetClosestPoint(Vector2D reference);
Vector2D GetClosestControlPoint(Vector2D reference); Vector2D GetClosestControlPoint(Vector2D reference);
}; };

View File

@ -61,9 +61,7 @@
#include "video_box.h" #include "video_box.h"
#include "video_context.h" #include "video_context.h"
#include "video_display.h" #include "video_display.h"
#include "video_provider_manager.h"
#include "video_slider.h" #include "video_slider.h"
#include "visual_tool.h"
/// @brief Constructor /// @brief Constructor
@ -171,8 +169,6 @@ BEGIN_EVENT_TABLE(VideoBox, wxPanel)
EVT_BUTTON(Video_Stop, VideoBox::OnVideoStop) EVT_BUTTON(Video_Stop, VideoBox::OnVideoStop)
EVT_TOGGLEBUTTON(Video_Auto_Scroll, VideoBox::OnVideoToggleScroll) EVT_TOGGLEBUTTON(Video_Auto_Scroll, VideoBox::OnVideoToggleScroll)
EVT_TOOL_RANGE(Video_Mode_Standard, Video_Mode_Vector_Clip, VideoBox::OnModeChange)
EVT_TOOL_RANGE(VISUAL_SUB_TOOL_START,VISUAL_SUB_TOOL_END, VideoBox::OnSubTool)
EVT_TOOL(Video_Mode_Realtime, VideoBox::OnToggleRealtime) EVT_TOOL(Video_Mode_Realtime, VideoBox::OnToggleRealtime)
EVT_TOOL(Video_Mode_Help, VideoBox::OnHelp) EVT_TOOL(Video_Mode_Help, VideoBox::OnHelp)
END_EVENT_TABLE() END_EVENT_TABLE()
@ -226,26 +222,6 @@ void VideoBox::OnVideoToggleScroll(wxCommandEvent &event) {
Options.Save(); Options.Save();
} }
/// @brief Mode changed
/// @param event
///
void VideoBox::OnModeChange(wxCommandEvent &event) {
videoDisplay->SetVisualMode(event.GetId() - Video_Mode_Standard);
}
/// @brief Sub-tool button pressed
/// @param event
///
void VideoBox::OnSubTool(wxCommandEvent &event) {
videoDisplay->OnSubTool(event);
}
/// @brief Realtime toggle /// @brief Realtime toggle
/// @param event /// @param event
/// ///

View File

@ -69,8 +69,6 @@ private:
void OnVideoStop(wxCommandEvent &event); void OnVideoStop(wxCommandEvent &event);
void OnVideoToggleScroll(wxCommandEvent &event); void OnVideoToggleScroll(wxCommandEvent &event);
void OnModeChange(wxCommandEvent &event);
void OnSubTool(wxCommandEvent &event);
void OnToggleRealtime(wxCommandEvent &event); void OnToggleRealtime(wxCommandEvent &event);
void OnHelp(wxCommandEvent &event); void OnHelp(wxCommandEvent &event);

View File

@ -73,7 +73,6 @@
#include "video_context.h" #include "video_context.h"
#include "video_display.h" #include "video_display.h"
#include "video_provider_manager.h" #include "video_provider_manager.h"
#include "visual_tool.h"
/////// ///////

View File

@ -53,16 +53,15 @@
#include <GL/glu.h> #include <GL/glu.h>
#endif #endif
#include "video_display.h"
#include "ass_dialogue.h" #include "ass_dialogue.h"
#include "hotkeys.h" #include "hotkeys.h"
#include "options.h" #include "options.h"
#include "utils.h"
#include "video_out_gl.h" #include "video_out_gl.h"
#include "vfr.h" #include "vfr.h"
#include "video_box.h" #include "video_box.h"
#include "video_context.h" #include "video_context.h"
#include "video_display.h"
#include "video_provider_manager.h"
#include "video_slider.h" #include "video_slider.h"
#include "visual_tool.h" #include "visual_tool.h"
#include "visual_tool_clip.h" #include "visual_tool_clip.h"
@ -88,7 +87,6 @@ enum {
VIDEO_MENU_SAVE_SNAPSHOT_RAW VIDEO_MENU_SAVE_SNAPSHOT_RAW
}; };
// Event table
BEGIN_EVENT_TABLE(VideoDisplay, wxGLCanvas) BEGIN_EVENT_TABLE(VideoDisplay, wxGLCanvas)
EVT_MOUSE_EVENTS(VideoDisplay::OnMouseEvent) EVT_MOUSE_EVENTS(VideoDisplay::OnMouseEvent)
EVT_KEY_DOWN(VideoDisplay::OnKey) EVT_KEY_DOWN(VideoDisplay::OnKey)
@ -106,31 +104,46 @@ END_EVENT_TABLE()
/// Attribute list for gl canvases; set the canvases to doublebuffered rgba with an 8 bit stencil buffer /// Attribute list for gl canvases; set the canvases to doublebuffered rgba with an 8 bit stencil buffer
int attribList[] = { WX_GL_RGBA , WX_GL_DOUBLEBUFFER, WX_GL_STENCIL_SIZE, 8, 0 }; int attribList[] = { WX_GL_RGBA , WX_GL_DOUBLEBUFFER, WX_GL_STENCIL_SIZE, 8, 0 };
/// @class VideoOutRenderException
/// @extends VideoOutException
/// @brief An OpenGL error occured while uploading or displaying a frame
class OpenGlException : public Aegisub::Exception {
public:
OpenGlException(const wxChar *func, int err)
: Aegisub::Exception(wxString::Format("%s failed with error code %d", func, err))
{ }
const wxChar * GetName() const { return L"video/opengl"; }
Exception * Copy() const { return new OpenGlException(*this); }
};
#define E(cmd) cmd; if (GLenum err = glGetError()) throw OpenGlException(L###cmd, err)
using std::min; using std::min;
VideoDisplay::VideoDisplay(VideoBox *box, VideoSlider *ControlSlider, wxTextCtrl *PositionDisplay, wxTextCtrl *SubsPosition, wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name) VideoDisplay::VideoDisplay(VideoBox *box, VideoSlider *ControlSlider, wxTextCtrl *PositionDisplay, wxTextCtrl *SubsPosition, wxWindow* parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name)
: wxGLCanvas (parent, id, attribList, pos, size, style, name) : wxGLCanvas (parent, id, attribList, pos, size, style, name)
, visualMode(-1)
, origSize(size) , origSize(size)
, currentFrame(-1) , currentFrame(-1)
, w(8), h(8), dx1(0), dx2(8), dy1(0), dy2(8) , w(8), h(8), viewport_x(0), viewport_width(0), viewport_bottom(0), viewport_top(0), viewport_height(0)
, mouse_x(INT_MIN), mouse_y(INT_MIN)
, locked(false) , locked(false)
, zoomValue(1.0) , zoomValue(1.0)
, ControlSlider(ControlSlider) , ControlSlider(ControlSlider)
, SubsPosition(SubsPosition) , SubsPosition(SubsPosition)
, PositionDisplay(PositionDisplay) , PositionDisplay(PositionDisplay)
, visual(NULL)
, videoOut(new VideoOutGL()) , videoOut(new VideoOutGL())
, box(box) , box(box)
, freeSize(false) , freeSize(false)
, tool(new VisualToolCross(this, video, box->visualSubToolBar))
, activeMode(Video_Mode_Standard)
, toolBar(box->visualSubToolBar)
, scriptW(INT_MIN)
, scriptH(INT_MIN)
{ {
box->Bind(wxEVT_COMMAND_TOOL_CLICKED, &VideoDisplay::OnMode, this, Video_Mode_Standard, Video_Mode_Vector_Clip);
SetCursor(wxNullCursor); SetCursor(wxNullCursor);
} }
VideoDisplay::~VideoDisplay () { VideoDisplay::~VideoDisplay () {
if (visual) delete visual;
visual = NULL;
VideoContext::Get()->RemoveDisplay(this); VideoContext::Get()->RemoveDisplay(this);
} }
@ -148,59 +161,62 @@ void VideoDisplay::SetFrame(int frameNumber) {
ControlSlider->SetValue(frameNumber); ControlSlider->SetValue(frameNumber);
// Get time for frame // Get time for frame
int time = VFR_Output.GetTimeAtFrame(frameNumber, true, true); {
int h = time / 3600000; int time = VFR_Output.GetTimeAtFrame(frameNumber, true, true);
int m = time % 3600000 / 60000; int h = time / 3600000;
int s = time % 60000 / 1000; int m = time % 3600000 / 60000;
int ms = time % 1000; int s = time % 60000 / 1000;
int ms = time % 1000;
// Set the text box for frame number and time // Set the text box for frame number and time
PositionDisplay->SetValue(wxString::Format(_T("%01i:%02i:%02i.%03i - %i"), h, m, s, ms, frameNumber)); PositionDisplay->SetValue(wxString::Format(L"%01i:%02i:%02i.%03i - %i", h, m, s, ms, frameNumber));
if (context->GetKeyFrames().Index(frameNumber) != wxNOT_FOUND) { if (context->GetKeyFrames().Index(frameNumber) != wxNOT_FOUND) {
// Set the background color to indicate this is a keyframe // Set the background color to indicate this is a keyframe
PositionDisplay->SetBackgroundColour(Options.AsColour(_T("Grid selection background"))); PositionDisplay->SetBackgroundColour(Options.AsColour(L"Grid selection background"));
PositionDisplay->SetForegroundColour(Options.AsColour(_T("Grid selection foreground"))); PositionDisplay->SetForegroundColour(Options.AsColour(L"Grid selection foreground"));
}
else {
PositionDisplay->SetBackgroundColour(wxNullColour);
PositionDisplay->SetForegroundColour(wxNullColour);
}
wxString startSign;
wxString endSign;
int startOff = 0;
int endOff = 0;
if (AssDialogue *curLine = context->curLine) {
startOff = time - curLine->Start.GetMS();
endOff = time - curLine->End.GetMS();
}
// Positive signs
if (startOff > 0) startSign = L"+";
if (endOff > 0) endSign = L"+";
// Set the text box for time relative to active subtitle line
SubsPosition->SetValue(wxString::Format(L"%s%ims; %s%ims", startSign.c_str(), startOff, endSign.c_str(), endOff));
} }
else {
PositionDisplay->SetBackgroundColour(wxNullColour);
PositionDisplay->SetForegroundColour(wxNullColour);
}
wxString startSign;
wxString endSign;
int startOff = 0;
int endOff = 0;
if (AssDialogue *curLine = context->curLine) {
startOff = time - curLine->Start.GetMS();
endOff = time - curLine->End.GetMS();
}
// Positive signs
if (startOff > 0) startSign = _T("+");
if (endOff > 0) endSign = _T("+");
// Set the text box for time relative to active subtitle line
SubsPosition->SetValue(wxString::Format(_T("%s%ims; %s%ims"), startSign.c_str(), startOff, endSign.c_str(), endOff));
if (IsShownOnScreen() && visual) visual->Refresh();
// Render the new frame // Render the new frame
if (context->IsLoaded()) { if (context->IsLoaded()) {
context->GetScriptSize(scriptW, scriptH);
tool->Refresh();
AegiVideoFrame frame; AegiVideoFrame frame;
try { try {
frame = context->GetFrame(frameNumber); frame = context->GetFrame(frameNumber);
} }
catch (const wxChar *err) { catch (const wxChar *err) {
wxLogError( wxLogError(
_T("Failed seeking video. The video file may be corrupt or incomplete.\n") L"Failed seeking video. The video file may be corrupt or incomplete.\n"
_T("Error message reported: %s"), L"Error message reported: %s",
err); err);
} }
catch (...) { catch (...) {
wxLogError( wxLogError(
_T("Failed seeking video. The video file may be corrupt or incomplete.\n") L"Failed seeking video. The video file may be corrupt or incomplete.\n"
_T("No further error message given.")); L"No further error message given.");
} }
try { try {
videoOut->UploadFrameData(frame); videoOut->UploadFrameData(frame);
@ -230,23 +246,41 @@ void VideoDisplay::SetFrameRange(int from, int to) {
void VideoDisplay::Render() try { void VideoDisplay::Render() try {
if (!IsShownOnScreen()) return; if (!IsShownOnScreen()) return;
wxASSERT(wxIsMainThread());
VideoContext *context = VideoContext::Get(); VideoContext *context = VideoContext::Get();
if (!context->IsLoaded()) return; if (!context->IsLoaded()) return;
assert(wxIsMainThread());
assert(w > 0);
SetCurrent(*context->GetGLContext(this)); SetCurrent(*context->GetGLContext(this));
int sw, sh; videoOut->Render(viewport_x, viewport_bottom, viewport_width, viewport_height);
context->GetScriptSize(sw, sh); E(glViewport(0, min(viewport_bottom, 0), w, h));
videoOut->SetViewport(dx1, dy1, dx2, dy2);
videoOut->Render(sw, sh);
DrawTVEffects(sw, sh); E(glMatrixMode(GL_PROJECTION));
E(glLoadIdentity());
E(glOrtho(0.0f, w, h, 0.0f, -1000.0f, 1000.0f));
if (visualMode == -1) SetVisualMode(0, false); if (Options.AsBool(L"Show Overscan Mask")) {
if (visual && (visual->mouseX > INT_MIN || visual->mouseY > INT_MIN || Options.AsBool(L"Always show visual tools"))) { double ar = context->GetAspectRatioValue();
visual->Draw();
// Based on BBC's guidelines: http://www.bbc.co.uk/guidelines/dq/pdf/tv/tv_standards_london.pdf
// 16:9 or wider
if (ar > 1.75) {
DrawOverscanMask(w * 0.1, h * 0.05, wxColor(30,70,200),0.5);
DrawOverscanMask(w * 0.035, h * 0.035, wxColor(30,70,200),0.5);
}
// Less wide than 16:9 (use 4:3 standard)
else {
DrawOverscanMask(w * 0.067, h * 0.05, wxColor(30,70,200),0.5);
DrawOverscanMask(w * 0.033, h * 0.035, wxColor(30,70,200),0.5);
}
}
if (video.x > INT_MIN ||
video.y > INT_MIN ||
Options.AsBool(L"Always show visual tools")) {
tool->Draw();
} }
glFinish(); glFinish();
@ -254,8 +288,15 @@ void VideoDisplay::Render() try {
} }
catch (const VideoOutException &err) { catch (const VideoOutException &err) {
wxLogError( wxLogError(
_T("An error occurred trying to render the video frame on the screen.\n") L"An error occurred trying to render the video frame on the screen.\n"
_T("Error message reported: %s"), L"Error message reported: %s",
err.GetMessage().c_str());
VideoContext::Get()->Reset();
}
catch (const OpenGlException &err) {
wxLogError(
L"An error occurred trying to render visual overlays on the screen.\n"
L"Error message reported: %s",
err.GetMessage().c_str()); err.GetMessage().c_str());
VideoContext::Get()->Reset(); VideoContext::Get()->Reset();
} }
@ -268,63 +309,37 @@ catch (const wchar_t *err) {
} }
catch (...) { catch (...) {
wxLogError( wxLogError(
_T("An error occurred trying to render the video frame to screen.\n") L"An error occurred trying to render the video frame to screen.\n"
_T("No further error message given.")); L"No further error message given.");
VideoContext::Get()->Reset(); VideoContext::Get()->Reset();
} }
void VideoDisplay::DrawTVEffects(int sw, int sh) { void VideoDisplay::DrawOverscanMask(int sizeH, int sizeV, wxColor color, double alpha) const {
bool drawOverscan = Options.AsBool(_T("Show Overscan Mask")); int rad1 = h * 0.05;
if (drawOverscan) {
// Get aspect ratio
double ar = VideoContext::Get()->GetAspectRatioValue();
// Based on BBC's guidelines: http://www.bbc.co.uk/guidelines/dq/pdf/tv/tv_standards_london.pdf
// 16:9 or wider
if (ar > 1.75) {
DrawOverscanMask(int(sw * 0.1),int(sh * 0.05),wxColour(30,70,200),0.5);
DrawOverscanMask(int(sw * 0.035),int(sh * 0.035),wxColour(30,70,200),0.5);
}
// Less wide than 16:9 (use 4:3 standard)
else {
DrawOverscanMask(int(sw * 0.067),int(sh * 0.05),wxColour(30,70,200),0.5);
DrawOverscanMask(int(sw * 0.033),int(sh * 0.035),wxColour(30,70,200),0.5);
}
}
}
void VideoDisplay::DrawOverscanMask(int sizeH,int sizeV,wxColour colour,double alpha) {
int sw,sh;
VideoContext *context = VideoContext::Get();
context->GetScriptSize(sw,sh);
int rad1 = int(sh * 0.05);
int gapH = sizeH+rad1; int gapH = sizeH+rad1;
int gapV = sizeV+rad1; int gapV = sizeV+rad1;
int rad2 = (int)sqrt(double(gapH*gapH + gapV*gapV))+1; int rad2 = sqrt(double(gapH*gapH + gapV*gapV)) + 1;
// Set up GL wrapper
OpenGLWrapper gl; OpenGLWrapper gl;
gl.SetFillColour(colour,alpha); E(gl.SetFillColour(color, alpha));
gl.SetLineColour(wxColour(0,0,0),0.0,1); gl.SetLineColour(wxColor(0, 0, 0), 0.0, 1);
// Draw sides // Draw sides
gl.DrawRectangle(gapH,0,sw-gapH,sizeV); // Top E(gl.DrawRectangle(gapH, 0, w-gapH, sizeV)); // Top
gl.DrawRectangle(sw-sizeH,gapV,sw,sh-gapV); // Right E(gl.DrawRectangle(w-sizeH, gapV, w, h-gapV)); // Right
gl.DrawRectangle(gapH,sh-sizeV,sw-gapH,sh); // Bottom E(gl.DrawRectangle(gapH, h-sizeV, w-gapH, h)); // Bottom
gl.DrawRectangle(0,gapV,sizeH,sh-gapV); // Left E(gl.DrawRectangle(0, gapV, sizeH, h-gapV)); // Left
// Draw rounded corners // Draw rounded corners
gl.DrawRing(gapH,gapV,rad1,rad2,1.0,180.0,270.0); // Top-left E(gl.DrawRing(gapH, gapV, rad1, rad2, 1.0, 180.0, 270.0)); // Top-left
gl.DrawRing(sw-gapH,gapV,rad1,rad2,1.0,90.0,180.0); // Top-right E(gl.DrawRing(w-gapH, gapV, rad1, rad2, 1.0, 90.0, 180.0)); // Top-right
gl.DrawRing(sw-gapH,sh-gapV,rad1,rad2,1.0,0.0,90.0); // Bottom-right E(gl.DrawRing(w-gapH, h-gapV, rad1, rad2, 1.0, 0.0, 90.0)); // Bottom-right
gl.DrawRing(gapH,sh-gapV,rad1,rad2,1.0,270.0,360.0); // Bottom-left E(gl.DrawRing(gapH, h-gapV, rad1, rad2, 1.0,270.0,360.0)); // Bottom-left
// Done E(glDisable(GL_BLEND));
glDisable(GL_BLEND);
} }
void VideoDisplay::UpdateSize() { void VideoDisplay::UpdateSize() {
VideoContext *con = VideoContext::Get(); VideoContext *con = VideoContext::Get();
wxASSERT(con); wxASSERT(con);
@ -336,10 +351,11 @@ void VideoDisplay::UpdateSize() {
if (freeSize) { if (freeSize) {
GetClientSize(&w,&h); GetClientSize(&w,&h);
dx1 = 0; viewport_x = 0;
dy1 = 0; viewport_bottom = 0;
dx2 = w; viewport_top = 0;
dy2 = h; viewport_width = w;
viewport_height = h;
// Set aspect ratio // Set aspect ratio
float displayAr = float(w) / float(h); float displayAr = float(w) / float(h);
@ -348,15 +364,15 @@ void VideoDisplay::UpdateSize() {
// Window is wider than video, blackbox left/right // Window is wider than video, blackbox left/right
if (displayAr - videoAr > 0.01f) { if (displayAr - videoAr > 0.01f) {
int delta = w - videoAr * h; int delta = w - videoAr * h;
dx1 = delta / 2; viewport_x = delta / 2;
dx2 = w - delta; viewport_width = w - delta;
} }
// Video is wider than window, blackbox top/bottom // Video is wider than window, blackbox top/bottom
else if (videoAr - displayAr > 0.01f) { else if (videoAr - displayAr > 0.01f) {
int delta = h - w / videoAr; int delta = h - w / videoAr;
dy1 = delta / 2; viewport_top = viewport_bottom = delta / 2;
dy2 = h - delta; viewport_height = h - delta;
} }
} }
else { else {
@ -371,12 +387,17 @@ void VideoDisplay::UpdateSize() {
// Cap the canvas size to the window size // Cap the canvas size to the window size
int cw = min(w, maxW), ch = min(h, maxH); int cw = min(w, maxW), ch = min(h, maxH);
viewport_x = 0;
viewport_bottom = ch - h;
viewport_top = 0;
viewport_width = w;
viewport_height = h;
// Sizers ignore SetClientSize/SetSize, so only use them to calculate // Sizers ignore SetClientSize/SetSize, so only use them to calculate
// what size is required after including the borders // what size is required after including the borders
SetClientSize(cw, ch); SetClientSize(cw, ch);
int fw, fh; GetSize(&cw, &ch);
GetSize(&fw, &fh); wxSize size(cw, ch);
wxSize size(fw, fh);
SetMinSize(size); SetMinSize(size);
SetMaxSize(size); SetMaxSize(size);
@ -387,16 +408,17 @@ void VideoDisplay::UpdateSize() {
// The sizer makes us use the full width, which at very low zoom levels // The sizer makes us use the full width, which at very low zoom levels
// results in stretched video, so after using the sizer to update the // results in stretched video, so after using the sizer to update the
// parent window sizes, reset our size to the correct value // parent window sizes, reset our size to the correct value
SetSize(fw, fh); SetSize(cw, ch);
locked = false; locked = false;
dx1 = 0;
dy1 = ch - h;
dx2 = w;
dy2 = h;
} }
con->GetScriptSize(scriptW, scriptH);
video.w = w;
video.h = h;
tool->Refresh();
Refresh(false); Refresh(false);
} }
@ -408,11 +430,10 @@ void VideoDisplay::Reset() {
wxASSERT(w > 0); wxASSERT(w > 0);
wxASSERT(h > 0); wxASSERT(h > 0);
SetClientSize(w,h); SetClientSize(w,h);
int _w,_h; GetSize(&w,&h);
GetSize(&_w,&_h); wxASSERT(w > 0);
wxASSERT(_w > 0); wxASSERT(h > 0);
wxASSERT(_h > 0); SetSizeHints(w,h,w,h);
SetSizeHints(_w,_h,_w,_h);
} }
void VideoDisplay::OnPaint(wxPaintEvent&) { void VideoDisplay::OnPaint(wxPaintEvent&) {
@ -427,9 +448,7 @@ void VideoDisplay::OnSizeEvent(wxSizeEvent &event) {
void VideoDisplay::OnMouseEvent(wxMouseEvent& event) { void VideoDisplay::OnMouseEvent(wxMouseEvent& event) {
if (locked) return; if (locked) return;
assert(w > 0);
mouse_x = event.GetX();
mouse_y = event.GetY();
// Disable when playing // Disable when playing
if (VideoContext::Get()->IsPlaying()) return; if (VideoContext::Get()->IsPlaying()) return;
@ -450,11 +469,15 @@ void VideoDisplay::OnMouseEvent(wxMouseEvent& event) {
return; return;
} }
<<<<<<< HEAD
// Enforce correct cursor display // Enforce correct cursor display
ShowCursor(visualMode != 0); ShowCursor(visualMode != 0);
// Click? // Click?
if (event.ButtonDown(wxMOUSE_BTN_ANY)) { if (event.ButtonDown(wxMOUSE_BTN_ANY)) {
=======
if (event.ButtonDown(wxMOUSE_BTN_ANY) || Options.AsBool(L"Video Autofocus")) {
>>>>>>> b1a392b... Make visual tools use only screen coordinates.
SetFocus(); SetFocus();
} }
int wheel = event.GetWheelRotation(); int wheel = event.GetWheelRotation();
@ -462,25 +485,34 @@ void VideoDisplay::OnMouseEvent(wxMouseEvent& event) {
SetZoom (zoomValue + .125 * (wheel / event.GetWheelDelta())); SetZoom (zoomValue + .125 * (wheel / event.GetWheelDelta()));
} }
// Send to visual if (event.Leaving()) {
if (visual) visual->OnMouseEvent(event); video.x = INT_MIN;
} video.y = INT_MIN;
}
else {
video.x = event.GetX();
video.y = event.GetY();
}
tool->OnMouseEvent(event);
ShowCursor(activeMode != Video_Mode_Standard);
Render();
}
void VideoDisplay::OnKey(wxKeyEvent &event) { void VideoDisplay::OnKey(wxKeyEvent &event) {
int key = event.GetKeyCode(); int key = event.GetKeyCode();
#ifdef __APPLE__ #ifdef __APPLE__
Hotkeys.SetPressed(key,event.m_metaDown,event.m_altDown,event.m_shiftDown); Hotkeys.SetPressed(key, event.m_metaDown, event.m_altDown, event.m_shiftDown);
#else #else
Hotkeys.SetPressed(key,event.m_controlDown,event.m_altDown,event.m_shiftDown); Hotkeys.SetPressed(key, event.m_controlDown, event.m_altDown, event.m_shiftDown);
#endif #endif
if (Hotkeys.IsPressed(_T("Visual Tool Default"))) SetVisualMode(0); if (Hotkeys.IsPressed(L"Visual Tool Default")) SetMode(Video_Mode_Standard);
else if (Hotkeys.IsPressed(_T("Visual Tool Drag"))) SetVisualMode(1); else if (Hotkeys.IsPressed(L"Visual Tool Drag")) SetMode(Video_Mode_Drag);
else if (Hotkeys.IsPressed(_T("Visual Tool Rotate Z"))) SetVisualMode(2); else if (Hotkeys.IsPressed(L"Visual Tool Rotate Z")) SetMode(Video_Mode_Rotate_Z);
else if (Hotkeys.IsPressed(_T("Visual Tool Rotate X/Y"))) SetVisualMode(3); else if (Hotkeys.IsPressed(L"Visual Tool Rotate X/Y")) SetMode(Video_Mode_Rotate_XY);
else if (Hotkeys.IsPressed(_T("Visual Tool Scale"))) SetVisualMode(4); else if (Hotkeys.IsPressed(L"Visual Tool Scale")) SetMode(Video_Mode_Scale);
else if (Hotkeys.IsPressed(_T("Visual Tool Rectangular Clip"))) SetVisualMode(5); else if (Hotkeys.IsPressed(L"Visual Tool Rectangular Clip")) SetMode(Video_Mode_Clip);
else if (Hotkeys.IsPressed(_T("Visual Tool Vector Clip"))) SetVisualMode(6); else if (Hotkeys.IsPressed(L"Visual Tool Vector Clip")) SetMode(Video_Mode_Vector_Clip);
event.Skip(); event.Skip();
} }
@ -499,10 +531,58 @@ void VideoDisplay::SetZoomFromBox() {
UpdateSize(); UpdateSize();
} }
} }
double VideoDisplay::GetZoom() { double VideoDisplay::GetZoom() const {
return zoomValue; return zoomValue;
} }
template<class T>
void VideoDisplay::SetTool() {
tool.reset(new T(this, video, toolBar));
box->Bind(wxEVT_COMMAND_TOOL_CLICKED, &T::OnSubTool, static_cast<T*>(tool.get()), VISUAL_SUB_TOOL_START, VISUAL_SUB_TOOL_END);
}
void VideoDisplay::OnMode(const wxCommandEvent &event) {
SetMode(event.GetId());
}
void VideoDisplay::SetMode(int mode) {
if (activeMode == mode) return;
toolBar->ClearTools();
toolBar->Realize();
toolBar->Show(false);
if (!box->visualToolBar->GetToolState(mode)) {
box->visualToolBar->ToggleTool(mode, true);
}
activeMode = mode;
switch (mode) {
case Video_Mode_Standard: SetTool<VisualToolCross>(); break;
case Video_Mode_Drag: SetTool<VisualToolDrag>(); break;
case Video_Mode_Rotate_Z: SetTool<VisualToolRotateZ>(); break;
case Video_Mode_Rotate_XY: SetTool<VisualToolRotateXY>(); break;
case Video_Mode_Scale: SetTool<VisualToolScale>(); break;
case Video_Mode_Clip: SetTool<VisualToolClip>(); break;
case Video_Mode_Vector_Clip: SetTool<VisualToolVectorClip>(); break;
default: assert(false); break;
}
// Update size as the new typesetting tool may have changed the subtoolbar size
UpdateSize();
}
void VideoDisplay::ToScriptCoords(int *x, int *y) const {
int sx = *x - viewport_x > 0 ? viewport_width : -viewport_width;
int sy = *y - viewport_top > 0 ? viewport_height : -viewport_height;
*x = ((*x - viewport_x) * scriptW + sx / 2) / viewport_width;
*y = ((*y - viewport_top) * scriptH + sy / 2) / viewport_height;
}
void VideoDisplay::FromScriptCoords(int *x, int *y) const {
int sx = *x > 0 ? scriptW : -scriptW;
int sy = *y > 0 ? scriptH : -scriptH;
*x = (*x * viewport_width + sx / 2) / scriptW + viewport_x;
*y = (*y * viewport_height + sy / 2) / scriptH + viewport_top;
}
void VideoDisplay::OnCopyToClipboard(wxCommandEvent &) { void VideoDisplay::OnCopyToClipboard(wxCommandEvent &) {
if (wxTheClipboard->Open()) { if (wxTheClipboard->Open()) {
wxTheClipboard->SetData(new wxBitmapDataObject(wxBitmap(VideoContext::Get()->GetFrame(-1).GetImage(),24))); wxTheClipboard->SetData(new wxBitmapDataObject(wxBitmap(VideoContext::Get()->GetFrame(-1).GetImage(),24)));
@ -527,55 +607,10 @@ void VideoDisplay::OnSaveSnapshotRaw(wxCommandEvent &) {
void VideoDisplay::OnCopyCoords(wxCommandEvent &) { void VideoDisplay::OnCopyCoords(wxCommandEvent &) {
if (wxTheClipboard->Open()) { if (wxTheClipboard->Open()) {
int sw,sh; int x = video.x;
VideoContext::Get()->GetScriptSize(sw,sh); int y = video.y;
int vx = (sw * mouse_x + w/2) / w; ToScriptCoords(&x, &y);
int vy = (sh * mouse_y + h/2) / h; wxTheClipboard->SetData(new wxTextDataObject(wxString::Format(L"%i,%i",x,y)));
wxTheClipboard->SetData(new wxTextDataObject(wxString::Format(_T("%i,%i"),vx,vy)));
wxTheClipboard->Close(); wxTheClipboard->Close();
} }
} }
void VideoDisplay::ConvertMouseCoords(int &x,int &y) {
x = (x-dx1)*w/dx2;
y = (y-dy1)*h/dy2;
}
void VideoDisplay::SetVisualMode(int mode, bool render) {
// Set visual
if (visualMode != mode) {
wxToolBar *toolBar = NULL;
if (box) {
toolBar = box->visualSubToolBar;
toolBar->ClearTools();
toolBar->Realize();
toolBar->Show(false);
if (!box->visualToolBar->GetToolState(mode + Video_Mode_Standard)) {
box->visualToolBar->ToggleTool(mode + Video_Mode_Standard,true);
}
}
// Replace mode
visualMode = mode;
delete visual;
switch (mode) {
case 0: visual = new VisualToolCross(this); break;
case 1: visual = new VisualToolDrag(this,toolBar); break;
case 2: visual = new VisualToolRotateZ(this); break;
case 3: visual = new VisualToolRotateXY(this); break;
case 4: visual = new VisualToolScale(this); break;
case 5: visual = new VisualToolClip(this); break;
case 6: visual = new VisualToolVectorClip(this,toolBar); break;
default: visual = NULL;
}
// Update size as the new typesetting tool may have changed the subtoolbar size
UpdateSize();
ControlSlider->Refresh(false);
}
if (render) Render();
}
void VideoDisplay::OnSubTool(wxCommandEvent &event) {
if (visual) visual->OnSubTool(event);
}

View File

@ -44,81 +44,77 @@
// Prototypes // Prototypes
class VideoSlider; class VideoSlider;
class VisualTool;
class VideoBox; class VideoBox;
class VideoOutGL; class VideoOutGL;
class VisualTool;
struct VideoState {
int x;
int y;
int w;
int h;
};
/// @class VideoDisplay /// @class VideoDisplay
/// @brief DOCME /// @brief DOCME
class VideoDisplay: public wxGLCanvas { class VideoDisplay: public wxGLCanvas {
private:
/// The current visual typesetting mode
int visualMode;
/// The unscaled size of the displayed video /// The unscaled size of the displayed video
wxSize origSize; wxSize origSize;
/// The frame number currently being displayed /// The frame number currently being displayed
int currentFrame; int currentFrame;
/// The width of the display /// The width of the canvas in screen pixels
int w; int w;
/// The height of the display /// The height of the canvas in screen pixels
int h; int h;
/// The x-coordinate of the bottom left of the area containing video. /// Screen pixels between the left of the canvas and the left of the video
/// Always zero unless the display is detatched and is wider than the video. int viewport_x;
int dx1; /// The width of the video in screen pixels
/// The width of the screen area containing video int viewport_width;
int dx2; /// Screen pixels between the bottom of the canvas and the bottom of the video; used for glViewport
/// The y-coordinate of the bottom left of the area containing video. int viewport_bottom;
/// Always zero unless the display is detatched and is taller than the video. /// Screen pixels between the bottom of the canvas and the top of the video; used for coordinate space conversion
int dy1; int viewport_top;
/// The height of the screen area containing video /// The height of the video in screen pixels
int dy2; int viewport_height;
/// The last seen x position of the mouse; stored for some context menu commands
int mouse_x;
/// The last seen y position of the mouse; stored for some context menu commands
int mouse_y;
/// Lock to disable mouse updates during resize operations /// Lock to disable mouse updates during resize operations
bool locked; bool locked;
/// @brief Draw the appropriate overscan masks for the current aspect ratio /// @brief Draw an overscan mask
void DrawTVEffects(int sh, int sw);
/// @brief Draw an overscan mask
/// @param sizeH The amount of horizontal overscan on one side /// @param sizeH The amount of horizontal overscan on one side
/// @param sizeV The amount of vertical overscan on one side /// @param sizeV The amount of vertical overscan on one side
/// @param colour The color of the mask /// @param colour The color of the mask
/// @param alpha The alpha of the mask /// @param alpha The alpha of the mask
void DrawOverscanMask(int sizeH,int sizeV,wxColour color,double alpha=0.5); void DrawOverscanMask(int sizeH, int sizeV, wxColor color, double alpha) const;
/// @brief Paint event /// @brief Paint event
void OnPaint(wxPaintEvent& event); void OnPaint(wxPaintEvent& event);
/// @brief Handle keypress events for switching visual typesetting modes /// @brief Key event handler
/// @param event /// @param event
void OnKey(wxKeyEvent &event); void OnKey(wxKeyEvent &event);
/// @brief Handle mouse events /// @brief Mouse event handler
/// @param event /// @param event
void OnMouseEvent(wxMouseEvent& event); void OnMouseEvent(wxMouseEvent& event);
/// @brief NOP event handler /// @brief NOP event handler
void OnEraseBackground(wxEraseEvent &event) {} void OnEraseBackground(wxEraseEvent &) {}
/// @brief Handle resize events /// @brief Recalculate video positioning and scaling when the available area or zoom changes
/// @param event /// @param event
void OnSizeEvent(wxSizeEvent &event); void OnSizeEvent(wxSizeEvent &event);
/// @brief Copy coordinates of the mouse to the clipboard /// @brief Copy coordinates of the mouse to the clipboard
void OnCopyCoords(wxCommandEvent &event); void OnCopyCoords(wxCommandEvent &);
/// @brief Copy the currently display frame to the clipboard, with subtitles /// @brief Copy the currently display frame to the clipboard, with subtitles
void OnCopyToClipboard(wxCommandEvent &event); void OnCopyToClipboard(wxCommandEvent &);
/// @brief Save the currently display frame to a file, with subtitles /// @brief Save the currently display frame to a file, with subtitles
void OnSaveSnapshot(wxCommandEvent &event); void OnSaveSnapshot(wxCommandEvent &);
/// @brief Copy the currently display frame to the clipboard, without subtitles /// @brief Copy the currently display frame to the clipboard, without subtitles
void OnCopyToClipboardRaw(wxCommandEvent &event); void OnCopyToClipboardRaw(wxCommandEvent &);
/// @brief Save the currently display frame to a file, without subtitles /// @brief Save the currently display frame to a file, without subtitles
void OnSaveSnapshotRaw(wxCommandEvent &event); void OnSaveSnapshotRaw(wxCommandEvent &);
/// The current zoom level, where 1.0 = 100% /// The current zoom level, where 1.0 = 100%
double zoomValue; double zoomValue;
@ -132,12 +128,30 @@ private:
/// The display for the absolute time of the video position /// The display for the absolute time of the video position
wxTextCtrl *PositionDisplay; wxTextCtrl *PositionDisplay;
/// The current visual typesetting tool
VisualTool *visual;
/// The video renderer /// The video renderer
std::auto_ptr<VideoOutGL> videoOut; std::auto_ptr<VideoOutGL> videoOut;
/// The active visual typesetting tool
std::auto_ptr<VisualTool> tool;
/// The current tool's ID
int activeMode;
/// The toolbar used by individual typesetting tools
wxToolBar* toolBar;
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
template <class T> void SetTool();
/// The current script width
int scriptW;
/// The current script height
int scriptH;
VideoState video;
public: public:
/// The VideoBox this display is contained in /// The VideoBox this display is contained in
VideoBox *box; VideoBox *box;
@ -176,10 +190,6 @@ public:
/// @brief Set the cursor to either default or blank /// @brief Set the cursor to either default or blank
/// @param show Whether or not the cursor should be visible /// @param show Whether or not the cursor should be visible
void ShowCursor(bool show); void ShowCursor(bool show);
/// @brief Convert mouse coordinates relative to the display to coordinates relative to the video
/// @param x X coordinate
/// @param y Y coordinate
void ConvertMouseCoords(int &x,int &y);
/// @brief Set the size of the display based on the current zoom and video resolution /// @brief Set the size of the display based on the current zoom and video resolution
void UpdateSize(); void UpdateSize();
/// @brief Set the zoom level /// @brief Set the zoom level
@ -188,14 +198,17 @@ public:
/// @brief Set the zoom level to that indicated by the dropdown /// @brief Set the zoom level to that indicated by the dropdown
void SetZoomFromBox(); void SetZoomFromBox();
/// @brief Get the current zoom level /// @brief Get the current zoom level
double GetZoom(); double GetZoom() const;
/// @brief Set the current visual typesetting mode
/// @param mode The new mode /// @brief Convert a point from screen to script coordinate frame
/// @param render Whether the display should be rerendered /// @param x x coordinate; in/out
void SetVisualMode(int mode, bool render = false); /// @param y y coordinate; in/out
void ToScriptCoords(int *x, int *y) const;
/// @brief Convert a point from script to screen coordinate frame
/// @param x x coordinate; in/out
/// @param y y coordinate; in/out
void FromScriptCoords(int *x, int *y) const;
/// @brief Event handler for the secondary toolbar which some visual tools use
void OnSubTool(wxCommandEvent &event);
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()
}; };

View File

@ -296,17 +296,10 @@ void VideoOutGL::UploadFrameData(const AegiVideoFrame& frame) {
CHECK_ERROR(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0)); CHECK_ERROR(glPixelStorei(GL_UNPACK_ROW_LENGTH, 0));
} }
void VideoOutGL::SetViewport(int x, int y, int width, int height) {
CHECK_ERROR(glViewport(x, y, width, height));
}
void VideoOutGL::Render(int sw, int sh) { void VideoOutGL::Render(int dx1, int dy1, int dx2, int dy2) {
CHECK_ERROR(glViewport(dx1, dy1, dx2, dy2));
glCallList(dl); glCallList(dl);
// Switch to script coordinates
// This isn't really the right place to do this, but there isn't really
// anywhere better right now
CHECK_ERROR(glOrtho(0.0f, sw, sh, 0.0f, -1000.0f, 1000.0f));
CHECK_ERROR(glMatrixMode(GL_MODELVIEW)); CHECK_ERROR(glMatrixMode(GL_MODELVIEW));
CHECK_ERROR(glLoadIdentity()); CHECK_ERROR(glLoadIdentity());

View File

@ -82,21 +82,16 @@ private:
VideoOutGL(const VideoOutGL &); VideoOutGL(const VideoOutGL &);
VideoOutGL& operator=(const VideoOutGL&); VideoOutGL& operator=(const VideoOutGL&);
public: public:
/// @brief Set the viewport
/// @param x Bottom left x coordinate
/// @param y Bottom left y coordinate
/// @param width Width in pixels of viewport
/// @param height Height in pixels of viewport
void SetViewport(int x, int y, int width, int height);
/// @brief Set the frame to be displayed when Render() is called /// @brief Set the frame to be displayed when Render() is called
/// @param frame The frame to be displayed /// @param frame The frame to be displayed
void UploadFrameData(const AegiVideoFrame& frame); void UploadFrameData(const AegiVideoFrame& frame);
/// @brief Render a frame /// @brief Render a frame
/// @param sw The current script width /// @param x Bottom left x coordinate
/// @param sh The current script height /// @param y Bottom left y coordinate
void Render(int sw, int sh); /// @param width Width in pixels of viewport
/// @param height Height in pixels of viewport
void Render(int x, int y, int width, int height);
/// @brief Constructor /// @brief Constructor
VideoOutGL(); VideoOutGL();

View File

@ -65,33 +65,22 @@
#include "video_provider_manager.h" #include "video_provider_manager.h"
#include "visual_tool.h" #include "visual_tool.h"
const wxColour VisualTool::colour[4] = {wxColour(106,32,19), wxColour(255,169,40), wxColour(255,253,185), wxColour(187,0,0)};
/// @brief Constructor /// @brief Constructor
/// @param par /// @param parent
/// VisualTool::VisualTool(VideoDisplay *parent, VideoState const& video)
VisualTool::VisualTool(VideoDisplay *par) : eventSink(this) { : parent(parent)
// Config , eventSink(this)
parent = par; , holding(false)
colour[0] = wxColour(106,32,19); , curDiag(NULL)
colour[1] = wxColour(255,169,40); , dragging(false)
colour[2] = wxColour(255,253,185); , curFeature(-1)
colour[3] = wxColour(187,0,0); , dragListOK(false)
, video(video)
// Holding variables , frame_n(0)
holding = false; {
curDiag = NULL;
// Dragging variables
dragging = false;
curFeature = -1;
dragListOK = false;
// Video options
mouseX = mouseY = INT_MIN;
frame_n = 0;
if (VideoContext::Get()->IsLoaded()) { if (VideoContext::Get()->IsLoaded()) {
parent->GetClientSize(&w,&h);
VideoContext::Get()->GetScriptSize(sw,sh);
frame_n = VideoContext::Get()->GetFrameN(); frame_n = VideoContext::Get()->GetFrameN();
} }
@ -99,43 +88,21 @@ VisualTool::VisualTool(VideoDisplay *par) : eventSink(this) {
if (CanDrag()) PopulateFeatureList(); if (CanDrag()) PopulateFeatureList();
} }
/// @brief Destructor /// @brief Destructor
///
VisualTool::~VisualTool() { VisualTool::~VisualTool() {
} }
/// @brief Mouse event /// @brief Mouse event
/// @param event /// @param event
/// @return
///
void VisualTool::OnMouseEvent (wxMouseEvent &event) { void VisualTool::OnMouseEvent (wxMouseEvent &event) {
// General variables bool realTime = Options.AsBool(L"Video Visual Realtime");
mouseX = event.GetX();
mouseY = event.GetY();
parent->ConvertMouseCoords(mouseX,mouseY);
parent->GetClientSize(&w,&h);
VideoContext::Get()->GetScriptSize(sw,sh);
frame_n = VideoContext::Get()->GetFrameN();
bool realTime = Options.AsBool(_T("Video Visual Realtime"));
// Mouse leaving control // Mouse leaving control
if (event.Leaving()) { if (event.Leaving()) {
mouseX = INT_MIN;
mouseY = INT_MIN;
mx = INT_MIN;
my = INT_MIN;
Update(); Update();
return; return;
} }
// Transformed mouse x/y
mx = mouseX * sw / w;
my = mouseY * sh / h;
// Clicks // Clicks
leftClick = event.ButtonDown(wxMOUSE_BTN_LEFT); leftClick = event.ButtonDown(wxMOUSE_BTN_LEFT);
leftDClick = event.LeftDClick(); leftDClick = event.LeftDClick();
@ -176,8 +143,8 @@ void VisualTool::OnMouseEvent (wxMouseEvent &event) {
} }
// Set start value // Set start value
dragStartX = mx; dragStartX = video.x;
dragStartY = my; dragStartY = video.y;
dragOrigX = features[curFeature].x; dragOrigX = features[curFeature].x;
dragOrigY = features[curFeature].y; dragOrigY = features[curFeature].y;
@ -192,8 +159,8 @@ void VisualTool::OnMouseEvent (wxMouseEvent &event) {
// Dragging // Dragging
if (event.LeftIsDown()) { if (event.LeftIsDown()) {
// Update position // Update position
features[curFeature].x = (mx - dragStartX + dragOrigX); features[curFeature].x = (video.x - dragStartX + dragOrigX);
features[curFeature].y = (my - dragStartY + dragOrigY); features[curFeature].y = (video.y - dragStartY + dragOrigY);
// Update drag // Update drag
UpdateDrag(features[curFeature]); UpdateDrag(features[curFeature]);
@ -276,12 +243,8 @@ void VisualTool::OnMouseEvent (wxMouseEvent &event) {
Update(); Update();
} }
/// @brief Commit /// @brief Commit
/// @param full /// @param full
/// @return
///
void VisualTool::Commit(bool full) { void VisualTool::Commit(bool full) {
// Get grid // Get grid
SubtitlesGrid *grid = VideoContext::Get()->grid; SubtitlesGrid *grid = VideoContext::Get()->grid;
@ -303,7 +266,6 @@ void VisualTool::Commit(bool full) {
/// @brief Get active dialogue line /// @brief Get active dialogue line
/// @return /// @return
///
AssDialogue* VisualTool::GetActiveDialogueLine() { AssDialogue* VisualTool::GetActiveDialogueLine() {
SubtitlesGrid *grid = VideoContext::Get()->grid; SubtitlesGrid *grid = VideoContext::Get()->grid;
AssDialogue *diag = grid->GetDialogue(grid->editBox->linen); AssDialogue *diag = grid->GetDialogue(grid->editBox->linen);
@ -320,16 +282,13 @@ AssDialogue* VisualTool::GetActiveDialogueLine() {
return diag; return diag;
} }
/// @brief Get feature under mouse /// @brief Get feature under mouse
/// @return /// @return
///
int VisualTool::GetHighlightedFeature() { int VisualTool::GetHighlightedFeature() {
int highestLayerFound = -99999; int highestLayerFound = INT_MIN;
int bestMatch = -1; int bestMatch = -1;
for (size_t i=0;i<features.size();i++) { for (size_t i=0;i<features.size();i++) {
if (features[i].IsMouseOver(mx,my) && features[i].layer > highestLayerFound) { if (features[i].IsMouseOver(video.x, video.y) && features[i].layer > highestLayerFound) {
bestMatch = i; bestMatch = i;
highestLayerFound = features[i].layer; highestLayerFound = features[i].layer;
} }
@ -337,10 +296,7 @@ int VisualTool::GetHighlightedFeature() {
return bestMatch; return bestMatch;
} }
/// @brief Draw all features /// @brief Draw all features
///
void VisualTool::DrawAllFeatures() { void VisualTool::DrawAllFeatures() {
// Populate list, if needed // Populate list, if needed
if (!dragListOK) { if (!dragListOK) {
@ -360,23 +316,17 @@ void VisualTool::DrawAllFeatures() {
} }
} }
/// @brief Refresh /// @brief Refresh
///
void VisualTool::Refresh() { void VisualTool::Refresh() {
frame_n = VideoContext::Get()->GetFrameN(); frame_n = VideoContext::Get()->GetFrameN();
if (!dragging) dragListOK = false; if (!dragging) dragListOK = false;
DoRefresh(); DoRefresh();
} }
/// @brief Get position of line /// @brief Get position of line
/// @param diag /// @param diag
/// @param x /// @param x
/// @param y /// @param y
///
void VisualTool::GetLinePosition(AssDialogue *diag,int &x, int &y) { void VisualTool::GetLinePosition(AssDialogue *diag,int &x, int &y) {
int orgx=0,orgy=0; int orgx=0,orgy=0;
GetLinePosition(diag,x,y,orgx,orgy); GetLinePosition(diag,x,y,orgx,orgy);
@ -388,8 +338,6 @@ void VisualTool::GetLinePosition(AssDialogue *diag,int &x, int &y) {
/// @param y /// @param y
/// @param orgx /// @param orgx
/// @param orgy /// @param orgy
/// @return
///
void VisualTool::GetLinePosition(AssDialogue *diag,int &x, int &y, int &orgx, int &orgy) { void VisualTool::GetLinePosition(AssDialogue *diag,int &x, int &y, int &orgx, int &orgy) {
// No dialogue // No dialogue
if (!diag) { if (!diag) {
@ -426,8 +374,6 @@ void VisualTool::GetLinePosition(AssDialogue *diag,int &x, int &y, int &orgx, in
// Position // Position
bool posSet = false; bool posSet = false;
bool orgSet = false; bool orgSet = false;
int posx = INT_MIN;
int posy = INT_MIN;
// Overrides processing // Overrides processing
diag->ParseASSTags(); diag->ParseASSTags();
@ -435,43 +381,47 @@ void VisualTool::GetLinePosition(AssDialogue *diag,int &x, int &y, int &orgx, in
AssOverrideTag *tag; AssOverrideTag *tag;
size_t blockn = diag->Blocks.size(); size_t blockn = diag->Blocks.size();
for (size_t i=0;i<blockn;i++) { for (size_t i=0;i<blockn;i++) {
if (posSet && orgSet) break;
override = AssDialogueBlock::GetAsOverride(diag->Blocks.at(i)); override = AssDialogueBlock::GetAsOverride(diag->Blocks.at(i));
if (override) { if (override) {
for (size_t j=0;j<override->Tags.size();j++) { for (size_t j=0;j<override->Tags.size();j++) {
tag = override->Tags.at(j); tag = override->Tags.at(j);
// Position // Position
if ((tag->Name == _T("\\pos") || tag->Name == _T("\\move")) && tag->Params.size() >= 2) { if ((tag->Name == L"\\pos" || tag->Name == L"\\move") && tag->Params.size() >= 2) {
if (!posSet) { if (!posSet) {
posx = tag->Params[0]->AsInt(); x = tag->Params[0]->AsInt();
posy = tag->Params[1]->AsInt(); y = tag->Params[1]->AsInt();
posSet = true; posSet = true;
} }
} }
// Alignment // Alignment
else if ((tag->Name == _T("\\an") || tag->Name == _T("\\a")) && tag->Params.size() >= 1) { else if ((tag->Name == L"\\an" || tag->Name == L"\\a") && tag->Params.size() >= 1) {
align = tag->Params[0]->AsInt(); align = tag->Params[0]->AsInt();
if (tag->Name == _T("\\a")) { if (tag->Name == L"\\a") {
switch(align) { switch(align) {
case 1: align = 1; break; case 1: case 2: case 3:
case 2: align = 2; break; break;
case 3: align = 3; break; case 5: case 6: case 7:
case 5: align = 7; break; align += 2;
case 6: align = 8; break; break;
case 7: align = 9; break; case 9: case 10: case 11:
case 9: align = 4; break; align -= 5;
case 10: align = 5; break; break;
case 11: align = 6; break; default:
default: align = 2; break; align = 2;
break;
} }
} }
} }
// Origin // Origin
else if (!orgSet && tag->Name == _T("\\org") && tag->Params.size() >= 2) { else if (!orgSet && tag->Name == L"\\org" && tag->Params.size() >= 2) {
orgx = tag->Params[0]->AsInt(); orgx = tag->Params[0]->AsInt();
orgy = tag->Params[1]->AsInt(); orgy = tag->Params[1]->AsInt();
parent->FromScriptCoords(&orgx, &orgy);
orgSet = true; orgSet = true;
} }
} }
@ -479,28 +429,21 @@ void VisualTool::GetLinePosition(AssDialogue *diag,int &x, int &y, int &orgx, in
} }
diag->ClearBlocks(); diag->ClearBlocks();
// Got position if (!posSet) {
if (posSet) { // Alignment type
x = posx; int hor = (align - 1) % 3;
y = posy; int vert = (align - 1) / 3;
if (!orgSet) {
orgx = x; // Calculate positions
orgy = y; if (hor == 0) x = margin[0];
} else if (hor == 1) x = (margin[0] + margin[1])/2;
return; else if (hor == 2) x = margin[1];
if (vert == 0) y = margin[3];
else if (vert == 1) y = (margin[2] + margin[3])/2;
else if (vert == 2) y = margin[2];
} }
// Alignment type parent->FromScriptCoords(&x, &y);
int hor = (align - 1) % 3;
int vert = (align - 1) / 3;
// Calculate positions
if (hor == 0) x = margin[0];
else if (hor == 1) x = (margin[0] + margin[1])/2;
else if (hor == 2) x = margin[1];
if (vert == 0) y = margin[3];
else if (vert == 1) y = (margin[2] + margin[3])/2;
else if (vert == 2) y = margin[2];
// No origin? // No origin?
if (!orgSet) { if (!orgSet) {
@ -509,8 +452,6 @@ void VisualTool::GetLinePosition(AssDialogue *diag,int &x, int &y, int &orgx, in
} }
} }
/// @brief Get the destination of move, if any /// @brief Get the destination of move, if any
/// @param diag /// @param diag
/// @param hasMove /// @param hasMove
@ -520,8 +461,6 @@ void VisualTool::GetLinePosition(AssDialogue *diag,int &x, int &y, int &orgx, in
/// @param y2 /// @param y2
/// @param t1 /// @param t1
/// @param t2 /// @param t2
/// @return
///
void VisualTool::GetLineMove(AssDialogue *diag,bool &hasMove,int &x1,int &y1,int &x2,int &y2,int &t1,int &t2) { void VisualTool::GetLineMove(AssDialogue *diag,bool &hasMove,int &x1,int &y1,int &x2,int &y2,int &t1,int &t2) {
// Parse tags // Parse tags
hasMove = false; hasMove = false;
@ -538,12 +477,14 @@ void VisualTool::GetLineMove(AssDialogue *diag,bool &hasMove,int &x1,int &y1,int
tag = override->Tags.at(j); tag = override->Tags.at(j);
// Position // Position
if (tag->Name == _T("\\move") && tag->Params.size() >= 4) { if (tag->Name == L"\\move" && tag->Params.size() >= 4) {
hasMove = true; hasMove = true;
x1 = tag->Params[0]->AsInt(); x1 = tag->Params[0]->AsInt();
y1 = tag->Params[1]->AsInt(); y1 = tag->Params[1]->AsInt();
x2 = tag->Params[2]->AsInt(); x2 = tag->Params[2]->AsInt();
y2 = tag->Params[3]->AsInt(); y2 = tag->Params[3]->AsInt();
parent->FromScriptCoords(&x1, &y1);
parent->FromScriptCoords(&x2, &y2);
if (tag->Params.size() >= 6 && if (tag->Params.size() >= 6 &&
!tag->Params[4]->ommited && !tag->Params[4]->ommited &&
!tag->Params[5]->ommited) { !tag->Params[5]->ommited) {
@ -559,15 +500,11 @@ void VisualTool::GetLineMove(AssDialogue *diag,bool &hasMove,int &x1,int &y1,int
diag->ClearBlocks(); diag->ClearBlocks();
} }
/// @brief Get line's rotation /// @brief Get line's rotation
/// @param diag /// @param diag
/// @param rx /// @param rx
/// @param ry /// @param ry
/// @param rz /// @param rz
/// @return
///
void VisualTool::GetLineRotation(AssDialogue *diag,float &rx,float &ry,float &rz) { void VisualTool::GetLineRotation(AssDialogue *diag,float &rx,float &ry,float &rz) {
// Default values // Default values
rx = ry = rz = 0.0f; rx = ry = rz = 0.0f;
@ -590,13 +527,13 @@ void VisualTool::GetLineRotation(AssDialogue *diag,float &rx,float &ry,float &rz
if (override) { if (override) {
for (size_t j=0;j<override->Tags.size();j++) { for (size_t j=0;j<override->Tags.size();j++) {
tag = override->Tags.at(j); tag = override->Tags.at(j);
if (tag->Name == _T("\\frx") && tag->Params.size() == 1) { if (tag->Name == L"\\frx" && tag->Params.size() == 1) {
rx = tag->Params[0]->AsFloat(); rx = tag->Params[0]->AsFloat();
} }
if (tag->Name == _T("\\fry") && tag->Params.size() == 1) { if (tag->Name == L"\\fry" && tag->Params.size() == 1) {
ry = tag->Params[0]->AsFloat(); ry = tag->Params[0]->AsFloat();
} }
if ((tag->Name == _T("\\frz") || tag->Name == _T("\fr")) && tag->Params.size() == 1) { if ((tag->Name == L"\\frz" || tag->Name == L"\fr") && tag->Params.size() == 1) {
rz = tag->Params[0]->AsFloat(); rz = tag->Params[0]->AsFloat();
} }
} }
@ -604,14 +541,10 @@ void VisualTool::GetLineRotation(AssDialogue *diag,float &rx,float &ry,float &rz
diag->ClearBlocks(); diag->ClearBlocks();
} }
/// @brief Get line's scale /// @brief Get line's scale
/// @param diag /// @param diag
/// @param scalX /// @param scalX
/// @param scalY /// @param scalY
/// @return
///
void VisualTool::GetLineScale(AssDialogue *diag,float &scalX,float &scalY) { void VisualTool::GetLineScale(AssDialogue *diag,float &scalX,float &scalY) {
// Default values // Default values
scalX = scalY = 100.0f; scalX = scalY = 100.0f;
@ -631,10 +564,10 @@ void VisualTool::GetLineScale(AssDialogue *diag,float &scalX,float &scalY) {
if (override) { if (override) {
for (size_t j=0;j<override->Tags.size();j++) { for (size_t j=0;j<override->Tags.size();j++) {
tag = override->Tags.at(j); tag = override->Tags.at(j);
if (tag->Name == _T("\\fscx") && tag->Params.size() == 1) { if (tag->Name == L"\\fscx" && tag->Params.size() == 1) {
scalX = tag->Params[0]->AsFloat(); scalX = tag->Params[0]->AsFloat();
} }
if (tag->Name == _T("\\fscy") && tag->Params.size() == 1) { if (tag->Name == L"\\fscy" && tag->Params.size() == 1) {
scalY = tag->Params[0]->AsFloat(); scalY = tag->Params[0]->AsFloat();
} }
} }
@ -651,8 +584,6 @@ void VisualTool::GetLineScale(AssDialogue *diag,float &scalX,float &scalY) {
/// @param x2 /// @param x2
/// @param y2 /// @param y2
/// @param inverse /// @param inverse
/// @return
///
void VisualTool::GetLineClip(AssDialogue *diag,int &x1,int &y1,int &x2,int &y2,bool &inverse) { void VisualTool::GetLineClip(AssDialogue *diag,int &x1,int &y1,int &x2,int &y2,bool &inverse) {
// Default values // Default values
x1 = y1 = 0; x1 = y1 = 0;
@ -677,14 +608,14 @@ void VisualTool::GetLineClip(AssDialogue *diag,int &x1,int &y1,int &x2,int &y2,b
if (override) { if (override) {
for (size_t j=0;j<override->Tags.size();j++) { for (size_t j=0;j<override->Tags.size();j++) {
tag = override->Tags.at(j); tag = override->Tags.at(j);
if (tag->Name == _T("\\clip") && tag->Params.size() == 4) { if (tag->Name == L"\\clip" && tag->Params.size() == 4) {
x1 = tag->Params[0]->AsInt(); x1 = tag->Params[0]->AsInt();
y1 = tag->Params[1]->AsInt(); y1 = tag->Params[1]->AsInt();
x2 = tag->Params[2]->AsInt(); x2 = tag->Params[2]->AsInt();
y2 = tag->Params[3]->AsInt(); y2 = tag->Params[3]->AsInt();
inverse = false; inverse = false;
} }
else if (tag->Name == _T("\\iclip") && tag->Params.size() == 4) { else if (tag->Name == L"\\iclip" && tag->Params.size() == 4) {
x1 = tag->Params[0]->AsInt(); x1 = tag->Params[0]->AsInt();
y1 = tag->Params[1]->AsInt(); y1 = tag->Params[1]->AsInt();
x2 = tag->Params[2]->AsInt(); x2 = tag->Params[2]->AsInt();
@ -694,6 +625,9 @@ void VisualTool::GetLineClip(AssDialogue *diag,int &x1,int &y1,int &x2,int &y2,b
} }
} }
diag->ClearBlocks(); diag->ClearBlocks();
parent->FromScriptCoords(&x1, &y1);
parent->FromScriptCoords(&x2, &y2);
} }
@ -702,8 +636,6 @@ void VisualTool::GetLineClip(AssDialogue *diag,int &x1,int &y1,int &x2,int &y2,b
/// @param diag /// @param diag
/// @param scale /// @param scale
/// @param inverse /// @param inverse
/// @return
///
wxString VisualTool::GetLineVectorClip(AssDialogue *diag,int &scale,bool &inverse) { wxString VisualTool::GetLineVectorClip(AssDialogue *diag,int &scale,bool &inverse) {
// Prepare overrides // Prepare overrides
wxString result; wxString result;
@ -723,7 +655,7 @@ wxString VisualTool::GetLineVectorClip(AssDialogue *diag,int &scale,bool &invers
if (override) { if (override) {
for (size_t j=0;j<override->Tags.size();j++) { for (size_t j=0;j<override->Tags.size();j++) {
tag = override->Tags.at(j); tag = override->Tags.at(j);
if (tag->Name == _T("\\clip") || tag->Name == _T("\\iclip")) { if (tag->Name == L"\\clip" || tag->Name == L"\\iclip") {
if (tag->Params.size() == 1) { if (tag->Params.size() == 1) {
result = tag->Params[0]->AsText(); result = tag->Params[0]->AsText();
} }
@ -736,9 +668,9 @@ wxString VisualTool::GetLineVectorClip(AssDialogue *diag,int &scale,bool &invers
y1 = tag->Params[1]->AsInt(), y1 = tag->Params[1]->AsInt(),
x2 = tag->Params[2]->AsInt(), x2 = tag->Params[2]->AsInt(),
y2 = tag->Params[3]->AsInt(); y2 = tag->Params[3]->AsInt();
result = wxString::Format(_T("m %d %d l %d %d %d %d %d %d"), x1, y1, x2, y1, x2, y2, x1, y2); result = wxString::Format(L"m %d %d l %d %d %d %d %d %d", x1, y1, x2, y1, x2, y2, x1, y2);
} }
inverse = tag->Name == _T("\\iclip"); inverse = tag->Name == L"\\iclip";
} }
} }
} }
@ -746,42 +678,28 @@ wxString VisualTool::GetLineVectorClip(AssDialogue *diag,int &scale,bool &invers
return result; return result;
} }
/// @brief Set override /// @brief Set override
/// @param tag /// @param tag
/// @param value /// @param value
///
void VisualTool::SetOverride(wxString tag,wxString value) { void VisualTool::SetOverride(wxString tag,wxString value) {
VideoContext::Get()->grid->editBox->SetOverride(tag,value,0,false); VideoContext::Get()->grid->editBox->SetOverride(tag,value,0,false);
parent->SetFocus(); //parent->SetFocus();
} }
/// @brief Connect button /// @brief Connect button
/// @param button /// @param button
///
void VisualTool::ConnectButton(wxButton *button) { void VisualTool::ConnectButton(wxButton *button) {
button->Connect(wxEVT_COMMAND_BUTTON_CLICKED,wxCommandEventHandler(VisualToolEvent::OnButton),NULL,&eventSink); button->Connect(wxEVT_COMMAND_BUTTON_CLICKED,wxCommandEventHandler(VisualToolEvent::OnButton),NULL,&eventSink);
} }
/// @brief Event sink /// @brief Event sink
/// @param _tool /// @param _tool
///
VisualToolEvent::VisualToolEvent(VisualTool *_tool) { VisualToolEvent::VisualToolEvent(VisualTool *_tool) {
tool = _tool; tool = _tool;
} }
/// @brief DOCME /// @brief DOCME
/// @param event /// @param event
///
void VisualToolEvent::OnButton(wxCommandEvent &event) { void VisualToolEvent::OnButton(wxCommandEvent &event) {
tool->OnButton(event); tool->OnButton(event);
} }

View File

@ -57,6 +57,7 @@
class VideoDisplay; class VideoDisplay;
class AssDialogue; class AssDialogue;
class VisualTool; class VisualTool;
struct VideoState;
@ -96,17 +97,15 @@ class VisualTool : public OpenGLWrapper {
friend class VisualToolEvent; friend class VisualToolEvent;
private: private:
/// DOCME
VideoDisplay *parent;
/// DOCME /// DOCME
VisualToolEvent eventSink; VisualToolEvent eventSink;
protected: protected:
/// DOCME
VideoDisplay *parent;
/// DOCME /// DOCME
wxColour colour[4]; static const wxColour colour[4];
/// DOCME /// DOCME
@ -138,22 +137,11 @@ protected:
bool dragListOK; bool dragListOK;
/// DOCME
/// DOCME
/// DOCME
/// DOCME
/// DOCME
/// DOCME
int w,h,sw,sh,mx,my;
/// DOCME /// DOCME
int frame_n; int frame_n;
VideoState const& video;
/// DOCME /// DOCME
bool leftClick; bool leftClick;
@ -181,10 +169,6 @@ protected:
void SetOverride(wxString tag,wxString value); void SetOverride(wxString tag,wxString value);
/// @brief DOCME
/// @return
///
VideoDisplay *GetParent() { return parent; }
AssDialogue *GetActiveDialogueLine(); AssDialogue *GetActiveDialogueLine();
int GetHighlightedFeature(); int GetHighlightedFeature();
void DrawAllFeatures(); void DrawAllFeatures();
@ -263,23 +247,17 @@ protected:
virtual void DoRefresh() {} virtual void DoRefresh() {}
public: public:
/// DOCME
/// DOCME
int mouseX,mouseY;
void OnMouseEvent(wxMouseEvent &event); void OnMouseEvent(wxMouseEvent &event);
/// @brief DOCME /// @brief DOCME
/// @param event /// @param event
/// ///
virtual void OnSubTool(wxCommandEvent &event) {} virtual void OnSubTool(wxCommandEvent &event) {}
virtual void Update()=0; virtual void Update() { };
virtual void Draw()=0; virtual void Draw()=0;
void Refresh(); void Refresh();
VisualTool(VideoDisplay *parent); VisualTool(VideoDisplay *parent, VideoState const& video);
virtual ~VisualTool(); virtual ~VisualTool();
}; };

View File

@ -51,34 +51,19 @@
/// @brief Constructor /// @brief Constructor
/// @param _parent /// @param _parent
/// ///
VisualToolClip::VisualToolClip(VideoDisplay *_parent) VisualToolClip::VisualToolClip(VideoDisplay *parent, VideoState const& video, wxToolBar *)
: VisualTool(_parent) : VisualTool(parent, video)
, curX1(0)
, curY1(0)
, curX2(video.w)
, curY2(video.h)
, inverse(false)
{ {
_parent->ShowCursor(false);
// Set defaults
curX1 = curY1 = 0;
curX2 = sw;
curY2 = sh;
inverse = false;
AssDialogue *line = GetActiveDialogueLine(); AssDialogue *line = GetActiveDialogueLine();
if (line) GetLineClip(line,curX1,curY1,curX2,curY2,inverse); if (line) GetLineClip(line,curX1,curY1,curX2,curY2,inverse);
} }
/// @brief Update
///
void VisualToolClip::Update() {
// Render parent
GetParent()->Render();
}
/// @brief Draw /// @brief Draw
/// @return
///
void VisualToolClip::Draw() { void VisualToolClip::Draw() {
// Get current line // Get current line
AssDialogue *line = GetActiveDialogueLine(); AssDialogue *line = GetActiveDialogueLine();
@ -103,10 +88,10 @@ void VisualToolClip::Draw() {
DrawRectangle(dx1,dy1,dx2,dy2); DrawRectangle(dx1,dy1,dx2,dy2);
} }
else { else {
DrawRectangle(0,0,sw,dy1); DrawRectangle(0,0,video.w,dy1);
DrawRectangle(0,dy2,sw,sh); DrawRectangle(0,dy2,video.w,video.h);
DrawRectangle(0,dy1,dx1,dy2); DrawRectangle(0,dy1,dx1,dy2);
DrawRectangle(dx2,dy1,sw,dy2); DrawRectangle(dx2,dy1,video.w,dy2);
} }
// Draw circles // Draw circles
@ -121,15 +106,12 @@ void VisualToolClip::Draw() {
} }
} }
/// @brief Start holding /// @brief Start holding
///
void VisualToolClip::InitializeHold() { void VisualToolClip::InitializeHold() {
startX = mouseX; startX = video.x;
startY = mouseY; startY = video.y;
curDiag->StripTag(_T("\\clip")); curDiag->StripTag(L"\\clip");
curDiag->StripTag(_T("\\iclip")); curDiag->StripTag(L"\\iclip");
} }
@ -138,20 +120,20 @@ void VisualToolClip::InitializeHold() {
/// ///
void VisualToolClip::UpdateHold() { void VisualToolClip::UpdateHold() {
// Coordinates // Coordinates
curX1 = startX * sw / w; curX1 = startX;
curY1 = startY * sh / h; curY1 = startY;
curX2 = mouseX * sw / w; curX2 = video.x;
curY2 = mouseY * sh / h; curY2 = video.y;
// Make sure 1 is smaller than 2 // Make sure 1 is smaller than 2
if (curX1 > curX2) IntSwap(curX1,curX2); if (curX1 > curX2) IntSwap(curX1,curX2);
if (curY1 > curY2) IntSwap(curY1,curY2); if (curY1 > curY2) IntSwap(curY1,curY2);
// Limit to video area // Limit to video area
curX1 = MID(0,curX1,sw); curX1 = MID(0,curX1,video.w);
curX2 = MID(0,curX2,sw); curX2 = MID(0,curX2,video.w);
curY1 = MID(0,curY1,sh); curY1 = MID(0,curY1,video.h);
curY2 = MID(0,curY2,sh); curY2 = MID(0,curY2,video.h);
// Features // Features
if (CanDrag()) PopulateFeatureList(); if (CanDrag()) PopulateFeatureList();
@ -162,10 +144,12 @@ void VisualToolClip::UpdateHold() {
/// @brief Commit hold /// @brief Commit hold
/// ///
void VisualToolClip::CommitHold() { void VisualToolClip::CommitHold() {
parent->ToScriptCoords(&curX1, &curY1);
parent->ToScriptCoords(&curX2, &curY2);
if (inverse) if (inverse)
SetOverride(_T("\\iclip"),wxString::Format(_T("(%i,%i,%i,%i)"),curX1,curY1,curX2,curY2)); SetOverride(L"\\iclip",wxString::Format(L"(%i,%i,%i,%i)",curX1,curY1,curX2,curY2));
else else
SetOverride(_T("\\clip"),wxString::Format(_T("(%i,%i,%i,%i)"),curX1,curY1,curX2,curY2)); SetOverride(L"\\clip",wxString::Format(L"(%i,%i,%i,%i)",curX1,curY1,curX2,curY2));
} }
@ -224,8 +208,8 @@ void VisualToolClip::PopulateFeatureList() {
/// ///
void VisualToolClip::InitializeDrag(VisualDraggableFeature &feature) { void VisualToolClip::InitializeDrag(VisualDraggableFeature &feature) {
curDiag = GetActiveDialogueLine(); curDiag = GetActiveDialogueLine();
curDiag->StripTag(_T("\\clip")); curDiag->StripTag(L"\\clip");
curDiag->StripTag(_T("\\iclip")); curDiag->StripTag(L"\\iclip");
} }
@ -257,5 +241,3 @@ void VisualToolClip::UpdateDrag(VisualDraggableFeature &feature) {
void VisualToolClip::CommitDrag(VisualDraggableFeature &feature) { void VisualToolClip::CommitDrag(VisualDraggableFeature &feature) {
CommitHold(); CommitHold();
} }

View File

@ -85,10 +85,7 @@ private:
void CommitDrag(VisualDraggableFeature &feature); void CommitDrag(VisualDraggableFeature &feature);
public: public:
VisualToolClip(VideoDisplay *parent); VisualToolClip(VideoDisplay *parent, VideoState const& video, wxToolBar *);
void Update();
void Draw(); void Draw();
}; };

View File

@ -51,47 +51,32 @@
/// @brief Constructor /// @brief Constructor
/// @param _parent /// @param _parent
/// ///
VisualToolCross::VisualToolCross(VideoDisplay *_parent) VisualToolCross::VisualToolCross(VideoDisplay *parent, VideoState const& video, wxToolBar *)
: VisualTool(_parent) : VisualTool(parent, video)
{ {
_parent->ShowCursor(false);
} }
VisualToolCross::~VisualToolCross() { }
/// @brief Destructor
///
VisualToolCross::~VisualToolCross() {
GetParent()->ShowCursor(true);
}
/// @brief Update /// @brief Update
/// ///
void VisualToolCross::Update() { void VisualToolCross::Update() {
// Position // Position
if (leftDClick) { if (leftDClick) {
int vx = (sw * mouseX + w/2) / w; int vx = video.x;
int vy = (sh * mouseY + h/2) / h; int vy = video.y;
parent->ToScriptCoords(&vx, &vy);
SubtitlesGrid *grid = VideoContext::Get()->grid; SubtitlesGrid *grid = VideoContext::Get()->grid;
SetOverride(_T("\\pos"),wxString::Format(_T("(%i,%i)"),vx,vy)); SetOverride(L"\\pos",wxString::Format(L"(%i,%i)",vx,vy));
grid->editBox->CommitText(); grid->editBox->CommitText();
grid->ass->FlagAsModified(_("positioning")); grid->ass->FlagAsModified(_("positioning"));
grid->CommitChanges(false,true); grid->CommitChanges(false,true);
} }
// Render parent
GetParent()->Render();
} }
/// @brief Draw /// @brief Draw
///
void VisualToolCross::Draw() { void VisualToolCross::Draw() {
if (mouseX == INT_MIN || mouseY == INT_MIN) return;
// Draw cross // Draw cross
glDisable(GL_LINE_SMOOTH); glDisable(GL_LINE_SMOOTH);
glEnable(GL_COLOR_LOGIC_OP); glEnable(GL_COLOR_LOGIC_OP);
@ -99,38 +84,35 @@ void VisualToolCross::Draw() {
glLineWidth(1); glLineWidth(1);
glBegin(GL_LINES); glBegin(GL_LINES);
glColor3f(1.0f,1.0f,1.0f); glColor3f(1.0f,1.0f,1.0f);
glVertex2f(0,my); glVertex2f(0, video.y);
glVertex2f(sw,my); glVertex2f(video.w, video.y);
glVertex2f(mx,0); glVertex2f(video.x, 0);
glVertex2f(mx,sh); glVertex2f(video.x, video.h);
glEnd(); glEnd();
glDisable(GL_COLOR_LOGIC_OP); glDisable(GL_COLOR_LOGIC_OP);
// Switch display int tx,ty;
glMatrixMode(GL_PROJECTION); if (!wxGetMouseState().ShiftDown()) {
glPushMatrix(); tx = video.x;
glLoadIdentity(); ty = video.y;
glOrtho(0.0f,w,h,0.0f,-1000.0f,1000.0f); }
glMatrixMode(GL_MODELVIEW); else {
tx = video.w - video.x;
ty = video.h - video.y;
}
parent->ToScriptCoords(&tx, &ty);
wxString mouseText = wxString::Format(L"%i,%i", tx, ty);
// Text of current coords
int dx = mouseX;
int dy = mouseY;
int vx = (sw * dx + w/2) / w;
int vy = (sh * dy + h/2) / h;
wxString mouseText;
if (!wxGetMouseState().ShiftDown()) mouseText = wxString::Format(_T("%i,%i"),vx,vy);
else mouseText = wxString::Format(_T("%i,%i"),vx - sw,vy - sh);
// Setup gl text
int tw,th; int tw,th;
OpenGLText::SetFont(_T("Verdana"),12,true); OpenGLText::SetFont(L"Verdana", 12, true);
OpenGLText::SetColour(wxColour(255,255,255)); OpenGLText::SetColour(wxColour(255, 255, 255));
OpenGLText::GetExtent(mouseText,tw,th); OpenGLText::GetExtent(mouseText, tw, th);
// Calculate draw position // Calculate draw position
bool left = dx > w/2; int dx = video.x;
bool bottom = dy < h/2; int dy = video.y;
bool left = dx > video.w / 2;
bool bottom = dy < video.h / 2;
// Text draw coords // Text draw coords
if (left) dx -= tw + 4; if (left) dx -= tw + 4;
@ -139,12 +121,5 @@ void VisualToolCross::Draw() {
else dy -= th + 3; else dy -= th + 3;
// Draw text // Draw text
OpenGLText::Print(mouseText,dx,dy); OpenGLText::Print(mouseText, dx, dy);
// Restore matrix
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
} }

View File

@ -49,7 +49,7 @@
/// DOCME /// DOCME
class VisualToolCross : public VisualTool { class VisualToolCross : public VisualTool {
public: public:
VisualToolCross(VideoDisplay *parent); VisualToolCross(VideoDisplay *parent, VideoState const& video, wxToolBar *);
~VisualToolCross(); ~VisualToolCross();
void Update(); void Update();

View File

@ -65,16 +65,13 @@ enum {
/// @param _parent /// @param _parent
/// @param toolBar /// @param toolBar
/// ///
VisualToolDrag::VisualToolDrag(VideoDisplay *_parent,wxToolBar *toolBar) VisualToolDrag::VisualToolDrag(VideoDisplay *parent, VideoState const& video, wxToolBar * toolBar)
: VisualTool(_parent) : VisualTool(parent, video)
{ {
_parent->ShowCursor(false);
//toolBar->AddTool(BUTTON_TOGGLE_MOVE,_T("Toggle Move/Pos"),GETIMAGE(visual_move_conv_move_24));
toggleMove = new wxBitmapButton(toolBar,BUTTON_TOGGLE_MOVE,GETIMAGE(visual_move_conv_move_24),wxDefaultPosition); toggleMove = new wxBitmapButton(toolBar,BUTTON_TOGGLE_MOVE,GETIMAGE(visual_move_conv_move_24),wxDefaultPosition);
ConnectButton(toggleMove); ConnectButton(toggleMove);
toolBar->AddControl(toggleMove); toolBar->AddControl(toggleMove);
toggleMoveOnMove = true; toggleMoveOnMove = true;
//UpdateToggleButtons();
toolBar->Realize(); toolBar->Realize();
toolBar->Show(true); toolBar->Show(true);
} }
@ -122,10 +119,12 @@ void VisualToolDrag::OnButton(wxCommandEvent &event) {
bool hasMove; bool hasMove;
GetLinePosition(line,x1,y1); GetLinePosition(line,x1,y1);
GetLineMove(line,hasMove,x1,y1,x2,y2,t1,t2); GetLineMove(line,hasMove,x1,y1,x2,y2,t1,t2);
parent->ToScriptCoords(&x1, &y1);
parent->ToScriptCoords(&x2, &y2);
// Replace tag // Replace tag
if (hasMove) SetOverride(_T("\\pos"),wxString::Format(_T("(%i,%i)"),x1,y1)); if (hasMove) SetOverride(L"\\pos",wxString::Format(L"(%i,%i)",x1,y1));
else SetOverride(_T("\\move"),wxString::Format(_T("(%i,%i,%i,%i,%i,%i)"),x1,y1,x1,y1,0,line->End.GetMS() - line->Start.GetMS())); else SetOverride(L"\\move",wxString::Format(L"(%i,%i,%i,%i,%i,%i)",x1,y1,x1,y1,0,line->End.GetMS() - line->Start.GetMS()));
SubtitlesGrid *grid = VideoContext::Get()->grid; SubtitlesGrid *grid = VideoContext::Get()->grid;
grid->editBox->CommitText(); grid->editBox->CommitText();
grid->ass->FlagAsModified(_("visual typesetting")); grid->ass->FlagAsModified(_("visual typesetting"));
@ -144,16 +143,6 @@ void VisualToolDrag::DoRefresh() {
UpdateToggleButtons(); UpdateToggleButtons();
} }
/// @brief Update
///
void VisualToolDrag::Update() {
GetParent()->Render();
}
/// @brief Draw /// @brief Draw
/// ///
void VisualToolDrag::Draw() { void VisualToolDrag::Draw() {
@ -289,16 +278,6 @@ void VisualToolDrag::PopulateFeatureList() {
} }
} }
/// @brief Start dragging
/// @param feature
///
void VisualToolDrag::InitializeDrag(VisualDraggableFeature &feature) {
}
/// @brief Update drag /// @brief Update drag
/// @param feature /// @param feature
/// ///
@ -316,12 +295,18 @@ void VisualToolDrag::UpdateDrag(VisualDraggableFeature &feature) {
void VisualToolDrag::CommitDrag(VisualDraggableFeature &feature) { void VisualToolDrag::CommitDrag(VisualDraggableFeature &feature) {
// Origin // Origin
if (feature.type == DRAG_BIG_TRIANGLE) { if (feature.type == DRAG_BIG_TRIANGLE) {
SetOverride(_T("\\org"),wxString::Format(_T("(%i,%i)"),feature.x,feature.y)); int x = feature.x;
int y = feature.y;
parent->ToScriptCoords(&x, &y);
SetOverride(L"\\org",wxString::Format(L"(%i,%i)",x,y));
} }
// Position // Position
else if (feature.brother[0] == -1) { else if (feature.brother[0] == -1) {
SetOverride(_T("\\pos"),wxString::Format(_T("(%i,%i)"),feature.x,feature.y)); int x = feature.x;
int y = feature.y;
parent->ToScriptCoords(&x, &y);
SetOverride(L"\\pos",wxString::Format(L"(%i,%i)",x,y));
} }
// Move // Move
@ -332,8 +317,15 @@ void VisualToolDrag::CommitDrag(VisualDraggableFeature &feature) {
if (p1->type == DRAG_BIG_CIRCLE) p1 = &features[p1->brother[0]]; if (p1->type == DRAG_BIG_CIRCLE) p1 = &features[p1->brother[0]];
p2 = &features[p1->brother[0]]; p2 = &features[p1->brother[0]];
int x1 = p1->x;
int y1 = p1->y;
parent->ToScriptCoords(&x1, &y1);
int x2 = p2->x;
int y2 = p2->y;
parent->ToScriptCoords(&x2, &y2);
// Set override // Set override
SetOverride(_T("\\move"),wxString::Format(_T("(%i,%i,%i,%i,%i,%i)"),p1->x,p1->y,p2->x,p2->y,p1->value,p2->value)); SetOverride(L"\\move", wxString::Format(L"(%i,%i,%i,%i,%i,%i)", x1, y1, x2, y2, p1->value, p2->value));
} }
} }

View File

@ -66,7 +66,6 @@ private:
/// ///
bool CanDrag() { return true; } bool CanDrag() { return true; }
void PopulateFeatureList(); void PopulateFeatureList();
void InitializeDrag(VisualDraggableFeature &feature);
void UpdateDrag(VisualDraggableFeature &feature); void UpdateDrag(VisualDraggableFeature &feature);
void CommitDrag(VisualDraggableFeature &feature); void CommitDrag(VisualDraggableFeature &feature);
@ -75,10 +74,7 @@ private:
void DoRefresh(); void DoRefresh();
public: public:
VisualToolDrag(VideoDisplay *parent,wxToolBar *toolbar); VisualToolDrag(VideoDisplay *parent, VideoState const& video, wxToolBar *toolbar);
void Update();
void Draw(); void Draw();
}; };

View File

@ -51,27 +51,13 @@
/// @brief Constructor /// @brief Constructor
/// @param _parent /// @param _parent
/// ///
VisualToolRotateXY::VisualToolRotateXY(VideoDisplay *_parent) VisualToolRotateXY::VisualToolRotateXY(VideoDisplay *parent, VideoState const& video, wxToolBar *)
: VisualTool(_parent) : VisualTool(parent, video)
{ {
_parent->ShowCursor(false);
DoRefresh(); DoRefresh();
} }
/// @brief Update
///
void VisualToolRotateXY::Update() {
// Render parent
GetParent()->Render();
}
/// @brief Draw /// @brief Draw
/// @return
///
void VisualToolRotateXY::Draw() { void VisualToolRotateXY::Draw() {
// Get line to draw // Get line to draw
AssDialogue *line = GetActiveDialogueLine(); AssDialogue *line = GetActiveDialogueLine();
@ -188,12 +174,12 @@ void VisualToolRotateXY::Draw() {
void VisualToolRotateXY::InitializeHold() { void VisualToolRotateXY::InitializeHold() {
GetLinePosition(curDiag,odx,ody,orgx,orgy); GetLinePosition(curDiag,odx,ody,orgx,orgy);
GetLineRotation(curDiag,origAngleX,origAngleY,rz); GetLineRotation(curDiag,origAngleX,origAngleY,rz);
startAngleX = (orgy-mouseY*sh/h)*2.0; startAngleX = (orgy-video.x)*2.0;
startAngleY = (mouseX*sw/w-orgx)*2.0; startAngleY = (video.y-orgx)*2.0;
curAngleX = origAngleX; curAngleX = origAngleX;
curAngleY = origAngleY; curAngleY = origAngleY;
curDiag->StripTag(_T("\\frx")); curDiag->StripTag(L"\\frx");
curDiag->StripTag(_T("\\fry")); curDiag->StripTag(L"\\fry");
} }
@ -202,8 +188,8 @@ void VisualToolRotateXY::InitializeHold() {
/// ///
void VisualToolRotateXY::UpdateHold() { void VisualToolRotateXY::UpdateHold() {
// Find screen angles // Find screen angles
float screenAngleX = (orgy-mouseY*sh/h)*2.0; float screenAngleX = (orgy-video.x)*2.0;
float screenAngleY = (mouseX*sw/w-orgx)*2.0; float screenAngleY = (video.y-orgx)*2.0;
// Deltas // Deltas
float deltaX = screenAngleX - startAngleX; float deltaX = screenAngleX - startAngleX;
@ -235,8 +221,8 @@ void VisualToolRotateXY::UpdateHold() {
/// @brief Commit hold /// @brief Commit hold
/// ///
void VisualToolRotateXY::CommitHold() { void VisualToolRotateXY::CommitHold() {
SetOverride(_T("\\frx"),wxString::Format(_T("(%0.3g)"),curAngleX)); SetOverride(L"\\frx",wxString::Format(L"(%0.3g)",curAngleX));
SetOverride(_T("\\fry"),wxString::Format(_T("(%0.3g)"),curAngleY)); SetOverride(L"\\fry",wxString::Format(L"(%0.3g)",curAngleY));
} }
@ -273,7 +259,10 @@ void VisualToolRotateXY::UpdateDrag(VisualDraggableFeature &feature) {
/// @param feature /// @param feature
/// ///
void VisualToolRotateXY::CommitDrag(VisualDraggableFeature &feature) { void VisualToolRotateXY::CommitDrag(VisualDraggableFeature &feature) {
SetOverride(_T("\\org"),wxString::Format(_T("(%i,%i)"),feature.x,feature.y)); int x = feature.x;
int y = feature.y;
parent->ToScriptCoords(&x, &y);
SetOverride(L"\\org",wxString::Format(L"(%i,%i)",x,y));
} }

View File

@ -34,19 +34,11 @@
/// @ingroup visual_ts /// @ingroup visual_ts
/// ///
///////////
// Headers
#include "visual_tool.h" #include "visual_tool.h"
/// DOCME /// DOCME
/// @class VisualToolRotateXY /// @class VisualToolRotateXY
/// @brief DOCME /// @brief DOCME
///
/// DOCME
class VisualToolRotateXY : public VisualTool { class VisualToolRotateXY : public VisualTool {
private: private:
@ -96,10 +88,7 @@ private:
void DoRefresh(); void DoRefresh();
public: public:
VisualToolRotateXY(VideoDisplay *parent); VisualToolRotateXY(VideoDisplay *parent, VideoState const& video, wxToolBar *);
void Update();
void Draw(); void Draw();
}; };

View File

@ -51,27 +51,13 @@
/// @brief Constructor /// @brief Constructor
/// @param _parent /// @param _parent
/// ///
VisualToolRotateZ::VisualToolRotateZ(VideoDisplay *_parent) VisualToolRotateZ::VisualToolRotateZ(VideoDisplay *parent, VideoState const& video, wxToolBar *)
: VisualTool(_parent) : VisualTool(parent, video)
{ {
_parent->ShowCursor(false);
DoRefresh(); DoRefresh();
} }
/// @brief Update
///
void VisualToolRotateZ::Update() {
// Render parent
GetParent()->Render();
}
/// @brief Draw /// @brief Draw
/// @return
///
void VisualToolRotateZ::Draw() { void VisualToolRotateZ::Draw() {
// Get line to draw // Get line to draw
AssDialogue *line = GetActiveDialogueLine(); AssDialogue *line = GetActiveDialogueLine();
@ -162,7 +148,7 @@ void VisualToolRotateZ::Draw() {
// Draw line to mouse // Draw line to mouse
if (!dragging && GetHighlightedFeature() == -1) { if (!dragging && GetHighlightedFeature() == -1) {
SetLineColour(colour[0]); SetLineColour(colour[0]);
DrawLine(dx,dy,mx,my); DrawLine(dx,dy,video.x,video.y);
} }
} }
@ -172,11 +158,11 @@ void VisualToolRotateZ::Draw() {
/// ///
void VisualToolRotateZ::InitializeHold() { void VisualToolRotateZ::InitializeHold() {
GetLinePosition(curDiag,odx,ody,orgx,orgy); GetLinePosition(curDiag,odx,ody,orgx,orgy);
startAngle = atan2(double(orgy-mouseY*sh/h),double(mouseX*sw/w-orgx)) * 180.0 / 3.1415926535897932; startAngle = atan2(double(orgy-video.y),double(video.x-orgx)) * 180.0 / 3.1415926535897932;
GetLineRotation(curDiag,rx,ry,origAngle); GetLineRotation(curDiag,rx,ry,origAngle);
curAngle = origAngle; curAngle = origAngle;
curDiag->StripTag(_T("\\frz")); curDiag->StripTag(L"\\frz");
curDiag->StripTag(_T("\\fr")); curDiag->StripTag(L"\\fr");
} }
@ -185,7 +171,7 @@ void VisualToolRotateZ::InitializeHold() {
/// ///
void VisualToolRotateZ::UpdateHold() { void VisualToolRotateZ::UpdateHold() {
// Find angle // Find angle
float screenAngle = atan2(double(orgy-mouseY*sh/h),double(mouseX*sw/w-orgx)) * 180.0 / 3.1415926535897932; float screenAngle = atan2(double(orgy-video.y),double(video.x-orgx)) * 180.0 / 3.1415926535897932;
curAngle = screenAngle - startAngle + origAngle; curAngle = screenAngle - startAngle + origAngle;
while (curAngle < 0.0f) curAngle += 360.0f; while (curAngle < 0.0f) curAngle += 360.0f;
while (curAngle >= 360.0f) curAngle -= 360.0f; while (curAngle >= 360.0f) curAngle -= 360.0f;
@ -202,7 +188,7 @@ void VisualToolRotateZ::UpdateHold() {
/// @brief Commit hold /// @brief Commit hold
/// ///
void VisualToolRotateZ::CommitHold() { void VisualToolRotateZ::CommitHold() {
SetOverride(_T("\\frz"),wxString::Format(L"(%0.3g)",curAngle)); SetOverride(L"\\frz",wxString::Format(L"(%0.3g)",curAngle));
} }
@ -239,7 +225,10 @@ void VisualToolRotateZ::UpdateDrag(VisualDraggableFeature &feature) {
/// @param feature /// @param feature
/// ///
void VisualToolRotateZ::CommitDrag(VisualDraggableFeature &feature) { void VisualToolRotateZ::CommitDrag(VisualDraggableFeature &feature) {
SetOverride(_T("\\org"),wxString::Format(_T("(%i,%i)"),feature.x,feature.y)); int x = feature.x;
int y = feature.y;
parent->ToScriptCoords(&x, &y);
SetOverride(L"\\org",wxString::Format(L"(%i,%i)",x,y));
} }

View File

@ -34,11 +34,6 @@
/// @ingroup visual_ts /// @ingroup visual_ts
/// ///
///////////
// Headers
#include "visual_tool.h" #include "visual_tool.h"
@ -91,10 +86,7 @@ private:
void DoRefresh(); void DoRefresh();
public: public:
VisualToolRotateZ(VideoDisplay *parent); VisualToolRotateZ(VideoDisplay *parent, VideoState const& video, wxToolBar *);
void Update();
void Draw(); void Draw();
}; };

View File

@ -51,26 +51,12 @@
/// @brief Constructor /// @brief Constructor
/// @param _parent /// @param _parent
/// ///
VisualToolScale::VisualToolScale(VideoDisplay *_parent) VisualToolScale::VisualToolScale(VideoDisplay *parent, VideoState const& video, wxToolBar *)
: VisualTool(_parent) : VisualTool(parent, video)
{ {
_parent->ShowCursor(false);
} }
/// @brief Update
///
void VisualToolScale::Update() {
// Render parent
GetParent()->Render();
}
/// @brief Draw /// @brief Draw
/// @return
///
void VisualToolScale::Draw() { void VisualToolScale::Draw() {
// Get line to draw // Get line to draw
AssDialogue *line = GetActiveDialogueLine(); AssDialogue *line = GetActiveDialogueLine();
@ -87,8 +73,8 @@ void VisualToolScale::Draw() {
// Set dx/dy // Set dx/dy
int len = 160; int len = 160;
dx = MID(len/2+10,dx,sw-len/2-30); dx = MID(len/2+10,dx,video.w-len/2-30);
dy = MID(len/2+10,dy,sh-len/2-30); dy = MID(len/2+10,dy,video.h-len/2-30);
// Set colours // Set colours
SetLineColour(colour[0]); SetLineColour(colour[0]);
@ -144,8 +130,8 @@ void VisualToolScale::Draw() {
/// @brief Start holding /// @brief Start holding
/// ///
void VisualToolScale::InitializeHold() { void VisualToolScale::InitializeHold() {
startX = mouseX; startX = video.x;
startY = mouseY; startY = video.y;
GetLineScale(curDiag,origScaleX,origScaleY); GetLineScale(curDiag,origScaleX,origScaleY);
curScaleX = origScaleX; curScaleX = origScaleX;
curScaleY = origScaleY; curScaleY = origScaleY;
@ -159,8 +145,8 @@ void VisualToolScale::InitializeHold() {
/// ///
void VisualToolScale::UpdateHold() { void VisualToolScale::UpdateHold() {
// Deltas // Deltas
int deltaX = mouseX - startX; int deltaX = video.x - startX;
int deltaY = startY - mouseY; int deltaY = startY - video.y;
if (ctrlDown) { if (ctrlDown) {
if (abs(deltaX) >= abs(deltaY)) deltaY = 0; if (abs(deltaX) >= abs(deltaY)) deltaY = 0;
else deltaX = 0; else deltaX = 0;

View File

@ -34,19 +34,11 @@
/// @ingroup visual_ts /// @ingroup visual_ts
/// ///
///////////
// Headers
#include "visual_tool.h" #include "visual_tool.h"
/// DOCME /// DOCME
/// @class VisualToolScale /// @class VisualToolScale
/// @brief DOCME /// @brief DOCME
///
/// DOCME
class VisualToolScale : public VisualTool { class VisualToolScale : public VisualTool {
private: private:
@ -78,10 +70,7 @@ private:
void CommitHold(); void CommitHold();
public: public:
VisualToolScale(VideoDisplay *parent); VisualToolScale(VideoDisplay *parent, VideoState const& video, wxToolBar *);
void Update();
void Draw(); void Draw();
}; };

View File

@ -34,9 +34,10 @@
/// @ingroup visual_ts /// @ingroup visual_ts
/// ///
#ifndef AGI_PRE
#include <wx/toolbar.h>
#endif
///////////
// Headers
#include "config.h" #include "config.h"
#include "ass_dialogue.h" #include "ass_dialogue.h"
@ -83,14 +84,13 @@ enum {
/// @param parent /// @param parent
/// @param _toolBar /// @param _toolBar
/// ///
VisualToolVectorClip::VisualToolVectorClip(VideoDisplay *parent,wxToolBar *_toolBar) VisualToolVectorClip::VisualToolVectorClip(VideoDisplay *parent, VideoState const& video, wxToolBar * toolBar)
: VisualTool(parent) : VisualTool(parent, video), toolBar(toolBar), spline(*parent)
{ {
DoRefresh(); DoRefresh();
mode = 0; mode = 0;
// Create toolbar // Create toolbar
toolBar = _toolBar;
toolBar->AddTool(BUTTON_DRAG,_("Drag"),GETIMAGE(visual_vector_clip_drag_24),_("Drag control points."),wxITEM_CHECK); toolBar->AddTool(BUTTON_DRAG,_("Drag"),GETIMAGE(visual_vector_clip_drag_24),_("Drag control points."),wxITEM_CHECK);
toolBar->AddTool(BUTTON_LINE,_("Line"),GETIMAGE(visual_vector_clip_line_24),_("Appends a line."),wxITEM_CHECK); toolBar->AddTool(BUTTON_LINE,_("Line"),GETIMAGE(visual_vector_clip_line_24),_("Appends a line."),wxITEM_CHECK);
toolBar->AddTool(BUTTON_BICUBIC,_("Bicubic"),GETIMAGE(visual_vector_clip_bicubic_24),_("Appends a bezier bicubic curve."),wxITEM_CHECK); toolBar->AddTool(BUTTON_BICUBIC,_("Bicubic"),GETIMAGE(visual_vector_clip_bicubic_24),_("Appends a bezier bicubic curve."),wxITEM_CHECK);
@ -132,19 +132,7 @@ void VisualToolVectorClip::SetMode(int _mode) {
mode = _mode; mode = _mode;
} }
/// @brief Update
///
void VisualToolVectorClip::Update() {
GetParent()->Render();
}
/// @brief Draw /// @brief Draw
/// @return
///
void VisualToolVectorClip::Draw() { void VisualToolVectorClip::Draw() {
// Get line // Get line
AssDialogue *line = GetActiveDialogueLine(); AssDialogue *line = GetActiveDialogueLine();
@ -175,7 +163,7 @@ void VisualToolVectorClip::Draw() {
glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
SetLineColour(colour[3],0.0f); SetLineColour(colour[3],0.0f);
SetFillColour(wxColour(0,0,0),0.5f); SetFillColour(wxColour(0,0,0),0.5f);
DrawRectangle(0,0,sw,sh); DrawRectangle(0,0,video.w,video.h);
glDisable(GL_STENCIL_TEST); glDisable(GL_STENCIL_TEST);
// Get current position information for modes 3 and 4 // Get current position information for modes 3 and 4
@ -183,7 +171,7 @@ void VisualToolVectorClip::Draw() {
int highCurve = -1; int highCurve = -1;
if (mode == 3 || mode == 4) { if (mode == 3 || mode == 4) {
float t; float t;
spline.GetClosestParametricPoint(Vector2D(mx,my),highCurve,t,pt); spline.GetClosestParametricPoint(Vector2D(video.x,video.y),highCurve,t,pt);
} }
// Draw lines // Draw lines
@ -216,8 +204,8 @@ void VisualToolVectorClip::Draw() {
if (spline.curves.size()) { if (spline.curves.size()) {
SplineCurve *c0 = &spline.curves.front(); SplineCurve *c0 = &spline.curves.front();
SplineCurve *c1 = &spline.curves.back(); SplineCurve *c1 = &spline.curves.back();
DrawDashedLine(mx,my,c0->p1.x,c0->p1.y,6); DrawDashedLine(video.x,video.y,c0->p1.x,c0->p1.y,6);
DrawDashedLine(mx,my,c1->GetEndPoint().x,c1->GetEndPoint().y,6); DrawDashedLine(video.x,video.y,c1->GetEndPoint().x,c1->GetEndPoint().y,6);
} }
} }
@ -313,9 +301,9 @@ void VisualToolVectorClip::UpdateDrag(VisualDraggableFeature &feature) {
/// ///
void VisualToolVectorClip::CommitDrag(VisualDraggableFeature &feature) { void VisualToolVectorClip::CommitDrag(VisualDraggableFeature &feature) {
if (inverse) if (inverse)
SetOverride(_T("\\iclip"),_T("(") + spline.EncodeToASS() + _T(")")); SetOverride(L"\\iclip",L"(" + spline.EncodeToASS() + L")");
else else
SetOverride(_T("\\clip"),_T("(") + spline.EncodeToASS() + _T(")")); SetOverride(L"\\clip",L"(" + spline.EncodeToASS() + L")");
} }
@ -340,9 +328,9 @@ void VisualToolVectorClip::ClickedFeature(VisualDraggableFeature &feature) {
// Erase and save changes // Erase and save changes
spline.curves.erase(cur); spline.curves.erase(cur);
if (inverse) if (inverse)
SetOverride(_T("\\iclip"),_T("(") + spline.EncodeToASS() + _T(")")); SetOverride(L"\\iclip",L"(" + spline.EncodeToASS() + L")");
else else
SetOverride(_T("\\clip"),_T("(") + spline.EncodeToASS() + _T(")")); SetOverride(L"\\clip",L"(" + spline.EncodeToASS() + L")");
curFeature = -1; curFeature = -1;
Commit(true); Commit(true);
return; return;
@ -382,7 +370,7 @@ void VisualToolVectorClip::InitializeHold() {
// First point // First point
else { else {
curve.p1 = Vector2D(mx,my); curve.p1 = Vector2D(video.x,video.y);
curve.type = CURVE_POINT; curve.type = CURVE_POINT;
} }
@ -396,7 +384,7 @@ void VisualToolVectorClip::InitializeHold() {
Vector2D pt; Vector2D pt;
int curve; int curve;
float t; float t;
spline.GetClosestParametricPoint(Vector2D(mx,my),curve,t,pt); spline.GetClosestParametricPoint(Vector2D(video.x,video.y),curve,t,pt);
// Convert // Convert
if (mode == 3) { if (mode == 3) {
@ -442,9 +430,9 @@ void VisualToolVectorClip::InitializeHold() {
// Commit // Commit
if (inverse) if (inverse)
SetOverride(_T("\\iclip"),_T("(") + spline.EncodeToASS() + _T(")")); SetOverride(L"\\iclip",L"(" + spline.EncodeToASS() + L")");
else else
SetOverride(_T("\\clip"),_T("(") + spline.EncodeToASS() + _T(")")); SetOverride(L"\\clip",L"(" + spline.EncodeToASS() + L")");
Commit(true); Commit(true);
} }
@ -465,13 +453,13 @@ void VisualToolVectorClip::InitializeHold() {
void VisualToolVectorClip::UpdateHold() { void VisualToolVectorClip::UpdateHold() {
// Insert line // Insert line
if (mode == 1) { if (mode == 1) {
spline.curves.back().p2 = Vector2D(mx,my); spline.curves.back().p2 = Vector2D(video.x,video.y);
} }
// Insert bicubic // Insert bicubic
if (mode == 2) { if (mode == 2) {
SplineCurve &curve = spline.curves.back(); SplineCurve &curve = spline.curves.back();
curve.p4 = Vector2D(mx,my); curve.p4 = Vector2D(video.x,video.y);
// Control points // Control points
if (spline.curves.size() > 1) { if (spline.curves.size() > 1) {
@ -492,7 +480,7 @@ void VisualToolVectorClip::UpdateHold() {
if (mode == 6 || mode == 7) { if (mode == 6 || mode == 7) {
if (lastX != -100000 && lastY != -100000) { if (lastX != -100000 && lastY != -100000) {
// See if distance is enough // See if distance is enough
Vector2D delta(lastX-mx,lastY-my); Vector2D delta(lastX-video.x,lastY-video.y);
int len = (int)delta.Len(); int len = (int)delta.Len();
if (mode == 6 && len < 30) return; if (mode == 6 && len < 30) return;
if (mode == 7 && len < 60) return; if (mode == 7 && len < 60) return;
@ -501,11 +489,11 @@ void VisualToolVectorClip::UpdateHold() {
SplineCurve curve; SplineCurve curve;
curve.type = CURVE_LINE; curve.type = CURVE_LINE;
curve.p1 = Vector2D(lastX,lastY); curve.p1 = Vector2D(lastX,lastY);
curve.p2 = Vector2D(mx,my); curve.p2 = Vector2D(video.x,video.y);
spline.AppendCurve(curve); spline.AppendCurve(curve);
} }
lastX = mx; lastX = video.x;
lastY = my; lastY = video.y;
} }
} }
@ -520,9 +508,9 @@ void VisualToolVectorClip::CommitHold() {
// Save it // Save it
if (mode != 3 && mode != 4) { if (mode != 3 && mode != 4) {
if (inverse) if (inverse)
SetOverride(_T("\\iclip"),_T("(") + spline.EncodeToASS() + _T(")")); SetOverride(L"\\iclip",L"(" + spline.EncodeToASS() + L")");
else else
SetOverride(_T("\\clip"),_T("(") + spline.EncodeToASS() + _T(")")); SetOverride(L"\\clip",L"(" + spline.EncodeToASS() + L")");
} }
// End freedraw // End freedraw

View File

@ -34,24 +34,14 @@
/// @ingroup visual_ts /// @ingroup visual_ts
/// ///
///////////
// Headers
#ifndef AGI_PRE
#include <wx/toolbar.h>
#endif
#include "visual_tool.h" #include "visual_tool.h"
#include "spline.h" #include "spline.h"
class wxToolBar;
/// DOCME /// DOCME
/// @class VisualToolVectorClip /// @class VisualToolVectorClip
/// @brief DOCME /// @brief DOCME
///
/// DOCME
class VisualToolVectorClip : public VisualTool { class VisualToolVectorClip : public VisualTool {
private: private:
@ -95,13 +85,10 @@ private:
void ClickedFeature(VisualDraggableFeature &feature); void ClickedFeature(VisualDraggableFeature &feature);
void DoRefresh(); void DoRefresh();
void OnSubTool(wxCommandEvent &event);
public: public:
VisualToolVectorClip(VideoDisplay *parent,wxToolBar *toolbar); VisualToolVectorClip(VideoDisplay *parent, VideoState const& video, wxToolBar *toolbar);
void Update();
void Draw(); void Draw();
void OnSubTool(wxCommandEvent &event);
}; };