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

View file

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

View file

@ -61,9 +61,7 @@
#include "video_box.h"
#include "video_context.h"
#include "video_display.h"
#include "video_provider_manager.h"
#include "video_slider.h"
#include "visual_tool.h"
/// @brief Constructor
@ -171,8 +169,6 @@ BEGIN_EVENT_TABLE(VideoBox, wxPanel)
EVT_BUTTON(Video_Stop, VideoBox::OnVideoStop)
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_Help, VideoBox::OnHelp)
END_EVENT_TABLE()
@ -226,26 +222,6 @@ void VideoBox::OnVideoToggleScroll(wxCommandEvent &event) {
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
/// @param event
///

View file

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

View file

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

View file

@ -53,16 +53,15 @@
#include <GL/glu.h>
#endif
#include "video_display.h"
#include "ass_dialogue.h"
#include "hotkeys.h"
#include "options.h"
#include "utils.h"
#include "video_out_gl.h"
#include "vfr.h"
#include "video_box.h"
#include "video_context.h"
#include "video_display.h"
#include "video_provider_manager.h"
#include "video_slider.h"
#include "visual_tool.h"
#include "visual_tool_clip.h"
@ -88,7 +87,6 @@ enum {
VIDEO_MENU_SAVE_SNAPSHOT_RAW
};
// Event table
BEGIN_EVENT_TABLE(VideoDisplay, wxGLCanvas)
EVT_MOUSE_EVENTS(VideoDisplay::OnMouseEvent)
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
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;
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)
, visualMode(-1)
, origSize(size)
, currentFrame(-1)
, w(8), h(8), dx1(0), dx2(8), dy1(0), dy2(8)
, mouse_x(INT_MIN), mouse_y(INT_MIN)
, w(8), h(8), viewport_x(0), viewport_width(0), viewport_bottom(0), viewport_top(0), viewport_height(0)
, locked(false)
, zoomValue(1.0)
, ControlSlider(ControlSlider)
, SubsPosition(SubsPosition)
, PositionDisplay(PositionDisplay)
, visual(NULL)
, videoOut(new VideoOutGL())
, box(box)
, 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);
}
VideoDisplay::~VideoDisplay () {
if (visual) delete visual;
visual = NULL;
VideoContext::Get()->RemoveDisplay(this);
}
@ -148,59 +161,62 @@ void VideoDisplay::SetFrame(int frameNumber) {
ControlSlider->SetValue(frameNumber);
// Get time for frame
int time = VFR_Output.GetTimeAtFrame(frameNumber, true, true);
int h = time / 3600000;
int m = time % 3600000 / 60000;
int s = time % 60000 / 1000;
int ms = time % 1000;
{
int time = VFR_Output.GetTimeAtFrame(frameNumber, true, true);
int h = time / 3600000;
int m = time % 3600000 / 60000;
int s = time % 60000 / 1000;
int ms = time % 1000;
// Set the text box for frame number and time
PositionDisplay->SetValue(wxString::Format(_T("%01i:%02i:%02i.%03i - %i"), h, m, s, ms, frameNumber));
if (context->GetKeyFrames().Index(frameNumber) != wxNOT_FOUND) {
// Set the background color to indicate this is a keyframe
PositionDisplay->SetBackgroundColour(Options.AsColour(_T("Grid selection background")));
PositionDisplay->SetForegroundColour(Options.AsColour(_T("Grid selection foreground")));
// Set the text box for frame number and time
PositionDisplay->SetValue(wxString::Format(L"%01i:%02i:%02i.%03i - %i", h, m, s, ms, frameNumber));
if (context->GetKeyFrames().Index(frameNumber) != wxNOT_FOUND) {
// Set the background color to indicate this is a keyframe
PositionDisplay->SetBackgroundColour(Options.AsColour(L"Grid selection background"));
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
if (context->IsLoaded()) {
context->GetScriptSize(scriptW, scriptH);
tool->Refresh();
AegiVideoFrame frame;
try {
frame = context->GetFrame(frameNumber);
}
catch (const wxChar *err) {
wxLogError(
_T("Failed seeking video. The video file may be corrupt or incomplete.\n")
_T("Error message reported: %s"),
L"Failed seeking video. The video file may be corrupt or incomplete.\n"
L"Error message reported: %s",
err);
}
catch (...) {
wxLogError(
_T("Failed seeking video. The video file may be corrupt or incomplete.\n")
_T("No further error message given."));
L"Failed seeking video. The video file may be corrupt or incomplete.\n"
L"No further error message given.");
}
try {
videoOut->UploadFrameData(frame);
@ -230,23 +246,41 @@ void VideoDisplay::SetFrameRange(int from, int to) {
void VideoDisplay::Render() try {
if (!IsShownOnScreen()) return;
wxASSERT(wxIsMainThread());
VideoContext *context = VideoContext::Get();
if (!context->IsLoaded()) return;
assert(wxIsMainThread());
assert(w > 0);
SetCurrent(*context->GetGLContext(this));
int sw, sh;
context->GetScriptSize(sw, sh);
videoOut->SetViewport(dx1, dy1, dx2, dy2);
videoOut->Render(sw, sh);
videoOut->Render(viewport_x, viewport_bottom, viewport_width, viewport_height);
E(glViewport(0, min(viewport_bottom, 0), w, h));
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 (visual && (visual->mouseX > INT_MIN || visual->mouseY > INT_MIN || Options.AsBool(L"Always show visual tools"))) {
visual->Draw();
if (Options.AsBool(L"Show Overscan Mask")) {
double ar = context->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(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();
@ -254,8 +288,15 @@ void VideoDisplay::Render() try {
}
catch (const VideoOutException &err) {
wxLogError(
_T("An error occurred trying to render the video frame on the screen.\n")
_T("Error message reported: %s"),
L"An error occurred trying to render the video frame on the screen.\n"
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());
VideoContext::Get()->Reset();
}
@ -268,63 +309,37 @@ catch (const wchar_t *err) {
}
catch (...) {
wxLogError(
_T("An error occurred trying to render the video frame to screen.\n")
_T("No further error message given."));
L"An error occurred trying to render the video frame to screen.\n"
L"No further error message given.");
VideoContext::Get()->Reset();
}
void VideoDisplay::DrawTVEffects(int sw, int sh) {
bool drawOverscan = Options.AsBool(_T("Show Overscan Mask"));
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);
void VideoDisplay::DrawOverscanMask(int sizeH, int sizeV, wxColor color, double alpha) const {
int rad1 = h * 0.05;
int gapH = sizeH+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;
gl.SetFillColour(colour,alpha);
gl.SetLineColour(wxColour(0,0,0),0.0,1);
E(gl.SetFillColour(color, alpha));
gl.SetLineColour(wxColor(0, 0, 0), 0.0, 1);
// Draw sides
gl.DrawRectangle(gapH,0,sw-gapH,sizeV); // Top
gl.DrawRectangle(sw-sizeH,gapV,sw,sh-gapV); // Right
gl.DrawRectangle(gapH,sh-sizeV,sw-gapH,sh); // Bottom
gl.DrawRectangle(0,gapV,sizeH,sh-gapV); // Left
E(gl.DrawRectangle(gapH, 0, w-gapH, sizeV)); // Top
E(gl.DrawRectangle(w-sizeH, gapV, w, h-gapV)); // Right
E(gl.DrawRectangle(gapH, h-sizeV, w-gapH, h)); // Bottom
E(gl.DrawRectangle(0, gapV, sizeH, h-gapV)); // Left
// Draw rounded corners
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
gl.DrawRing(sw-gapH,sh-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, gapV, rad1, rad2, 1.0, 180.0, 270.0)); // Top-left
E(gl.DrawRing(w-gapH, gapV, rad1, rad2, 1.0, 90.0, 180.0)); // Top-right
E(gl.DrawRing(w-gapH, h-gapV, rad1, rad2, 1.0, 0.0, 90.0)); // Bottom-right
E(gl.DrawRing(gapH, h-gapV, rad1, rad2, 1.0,270.0,360.0)); // Bottom-left
// Done
glDisable(GL_BLEND);
E(glDisable(GL_BLEND));
}
void VideoDisplay::UpdateSize() {
VideoContext *con = VideoContext::Get();
wxASSERT(con);
@ -336,10 +351,11 @@ void VideoDisplay::UpdateSize() {
if (freeSize) {
GetClientSize(&w,&h);
dx1 = 0;
dy1 = 0;
dx2 = w;
dy2 = h;
viewport_x = 0;
viewport_bottom = 0;
viewport_top = 0;
viewport_width = w;
viewport_height = h;
// Set aspect ratio
float displayAr = float(w) / float(h);
@ -348,15 +364,15 @@ void VideoDisplay::UpdateSize() {
// Window is wider than video, blackbox left/right
if (displayAr - videoAr > 0.01f) {
int delta = w - videoAr * h;
dx1 = delta / 2;
dx2 = w - delta;
viewport_x = delta / 2;
viewport_width = w - delta;
}
// Video is wider than window, blackbox top/bottom
else if (videoAr - displayAr > 0.01f) {
int delta = h - w / videoAr;
dy1 = delta / 2;
dy2 = h - delta;
viewport_top = viewport_bottom = delta / 2;
viewport_height = h - delta;
}
}
else {
@ -371,12 +387,17 @@ void VideoDisplay::UpdateSize() {
// Cap the canvas size to the window size
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
// what size is required after including the borders
SetClientSize(cw, ch);
int fw, fh;
GetSize(&fw, &fh);
wxSize size(fw, fh);
GetSize(&cw, &ch);
wxSize size(cw, ch);
SetMinSize(size);
SetMaxSize(size);
@ -387,16 +408,17 @@ void VideoDisplay::UpdateSize() {
// 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
// parent window sizes, reset our size to the correct value
SetSize(fw, fh);
SetSize(cw, ch);
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);
}
@ -408,11 +430,10 @@ void VideoDisplay::Reset() {
wxASSERT(w > 0);
wxASSERT(h > 0);
SetClientSize(w,h);
int _w,_h;
GetSize(&_w,&_h);
wxASSERT(_w > 0);
wxASSERT(_h > 0);
SetSizeHints(_w,_h,_w,_h);
GetSize(&w,&h);
wxASSERT(w > 0);
wxASSERT(h > 0);
SetSizeHints(w,h,w,h);
}
void VideoDisplay::OnPaint(wxPaintEvent&) {
@ -427,9 +448,7 @@ void VideoDisplay::OnSizeEvent(wxSizeEvent &event) {
void VideoDisplay::OnMouseEvent(wxMouseEvent& event) {
if (locked) return;
mouse_x = event.GetX();
mouse_y = event.GetY();
assert(w > 0);
// Disable when playing
if (VideoContext::Get()->IsPlaying()) return;
@ -450,11 +469,15 @@ void VideoDisplay::OnMouseEvent(wxMouseEvent& event) {
return;
}
<<<<<<< HEAD
// Enforce correct cursor display
ShowCursor(visualMode != 0);
// Click?
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();
}
int wheel = event.GetWheelRotation();
@ -462,25 +485,34 @@ void VideoDisplay::OnMouseEvent(wxMouseEvent& event) {
SetZoom (zoomValue + .125 * (wheel / event.GetWheelDelta()));
}
// Send to visual
if (visual) visual->OnMouseEvent(event);
}
if (event.Leaving()) {
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) {
int key = event.GetKeyCode();
#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
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
if (Hotkeys.IsPressed(_T("Visual Tool Default"))) SetVisualMode(0);
else if (Hotkeys.IsPressed(_T("Visual Tool Drag"))) SetVisualMode(1);
else if (Hotkeys.IsPressed(_T("Visual Tool Rotate Z"))) SetVisualMode(2);
else if (Hotkeys.IsPressed(_T("Visual Tool Rotate X/Y"))) SetVisualMode(3);
else if (Hotkeys.IsPressed(_T("Visual Tool Scale"))) SetVisualMode(4);
else if (Hotkeys.IsPressed(_T("Visual Tool Rectangular Clip"))) SetVisualMode(5);
else if (Hotkeys.IsPressed(_T("Visual Tool Vector Clip"))) SetVisualMode(6);
if (Hotkeys.IsPressed(L"Visual Tool Default")) SetMode(Video_Mode_Standard);
else if (Hotkeys.IsPressed(L"Visual Tool Drag")) SetMode(Video_Mode_Drag);
else if (Hotkeys.IsPressed(L"Visual Tool Rotate Z")) SetMode(Video_Mode_Rotate_Z);
else if (Hotkeys.IsPressed(L"Visual Tool Rotate X/Y")) SetMode(Video_Mode_Rotate_XY);
else if (Hotkeys.IsPressed(L"Visual Tool Scale")) SetMode(Video_Mode_Scale);
else if (Hotkeys.IsPressed(L"Visual Tool Rectangular Clip")) SetMode(Video_Mode_Clip);
else if (Hotkeys.IsPressed(L"Visual Tool Vector Clip")) SetMode(Video_Mode_Vector_Clip);
event.Skip();
}
@ -499,10 +531,58 @@ void VideoDisplay::SetZoomFromBox() {
UpdateSize();
}
}
double VideoDisplay::GetZoom() {
double VideoDisplay::GetZoom() const {
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 &) {
if (wxTheClipboard->Open()) {
wxTheClipboard->SetData(new wxBitmapDataObject(wxBitmap(VideoContext::Get()->GetFrame(-1).GetImage(),24)));
@ -527,55 +607,10 @@ void VideoDisplay::OnSaveSnapshotRaw(wxCommandEvent &) {
void VideoDisplay::OnCopyCoords(wxCommandEvent &) {
if (wxTheClipboard->Open()) {
int sw,sh;
VideoContext::Get()->GetScriptSize(sw,sh);
int vx = (sw * mouse_x + w/2) / w;
int vy = (sh * mouse_y + h/2) / h;
wxTheClipboard->SetData(new wxTextDataObject(wxString::Format(_T("%i,%i"),vx,vy)));
int x = video.x;
int y = video.y;
ToScriptCoords(&x, &y);
wxTheClipboard->SetData(new wxTextDataObject(wxString::Format(L"%i,%i",x,y)));
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
class VideoSlider;
class VisualTool;
class VideoBox;
class VideoOutGL;
class VisualTool;
struct VideoState {
int x;
int y;
int w;
int h;
};
/// @class VideoDisplay
/// @brief DOCME
class VideoDisplay: public wxGLCanvas {
private:
/// The current visual typesetting mode
int visualMode;
/// The unscaled size of the displayed video
wxSize origSize;
/// The frame number currently being displayed
int currentFrame;
/// The width of the display
/// The width of the canvas in screen pixels
int w;
/// The height of the display
/// The height of the canvas in screen pixels
int h;
/// The x-coordinate of the bottom left of the area containing video.
/// Always zero unless the display is detatched and is wider than the video.
int dx1;
/// The width of the screen area containing video
int dx2;
/// The y-coordinate of the bottom left of the area containing video.
/// Always zero unless the display is detatched and is taller than the video.
int dy1;
/// The height of the screen area containing video
int dy2;
/// 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;
/// Screen pixels between the left of the canvas and the left of the video
int viewport_x;
/// The width of the video in screen pixels
int viewport_width;
/// Screen pixels between the bottom of the canvas and the bottom of the video; used for glViewport
int viewport_bottom;
/// Screen pixels between the bottom of the canvas and the top of the video; used for coordinate space conversion
int viewport_top;
/// The height of the video in screen pixels
int viewport_height;
/// Lock to disable mouse updates during resize operations
bool locked;
/// @brief Draw the appropriate overscan masks for the current aspect ratio
void DrawTVEffects(int sh, int sw);
/// @brief Draw an overscan mask
/// @brief Draw an overscan mask
/// @param sizeH The amount of horizontal overscan on one side
/// @param sizeV The amount of vertical overscan on one side
/// @param colour The color 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
void OnPaint(wxPaintEvent& event);
/// @brief Handle keypress events for switching visual typesetting modes
/// @param event
/// @brief Key event handler
/// @param event
void OnKey(wxKeyEvent &event);
/// @brief Handle mouse events
/// @brief Mouse event handler
/// @param event
void OnMouseEvent(wxMouseEvent& event);
/// @brief NOP event handler
void OnEraseBackground(wxEraseEvent &event) {}
/// @brief Handle resize events
void OnEraseBackground(wxEraseEvent &) {}
/// @brief Recalculate video positioning and scaling when the available area or zoom changes
/// @param event
void OnSizeEvent(wxSizeEvent &event);
/// @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
void OnCopyToClipboard(wxCommandEvent &event);
void OnCopyToClipboard(wxCommandEvent &);
/// @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
void OnCopyToClipboardRaw(wxCommandEvent &event);
void OnCopyToClipboardRaw(wxCommandEvent &);
/// @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%
double zoomValue;
@ -132,12 +128,30 @@ private:
/// The display for the absolute time of the video position
wxTextCtrl *PositionDisplay;
/// The current visual typesetting tool
VisualTool *visual;
/// The video renderer
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:
/// The VideoBox this display is contained in
VideoBox *box;
@ -176,10 +190,6 @@ public:
/// @brief Set the cursor to either default or blank
/// @param show Whether or not the cursor should be visible
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
void UpdateSize();
/// @brief Set the zoom level
@ -188,14 +198,17 @@ public:
/// @brief Set the zoom level to that indicated by the dropdown
void SetZoomFromBox();
/// @brief Get the current zoom level
double GetZoom();
/// @brief Set the current visual typesetting mode
/// @param mode The new mode
/// @param render Whether the display should be rerendered
void SetVisualMode(int mode, bool render = false);
double GetZoom() const;
/// @brief Convert a point from screen to script coordinate frame
/// @param x x coordinate; in/out
/// @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()
};

View file

@ -296,17 +296,10 @@ void VideoOutGL::UploadFrameData(const AegiVideoFrame& frame) {
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);
// 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(glLoadIdentity());

View file

@ -82,21 +82,16 @@ private:
VideoOutGL(const VideoOutGL &);
VideoOutGL& operator=(const VideoOutGL&);
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
/// @param frame The frame to be displayed
void UploadFrameData(const AegiVideoFrame& frame);
/// @brief Render a frame
/// @param sw The current script width
/// @param sh The current script height
void Render(int sw, int sh);
/// @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 Render(int x, int y, int width, int height);
/// @brief Constructor
VideoOutGL();

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -65,16 +65,13 @@ enum {
/// @param _parent
/// @param toolBar
///
VisualToolDrag::VisualToolDrag(VideoDisplay *_parent,wxToolBar *toolBar)
: VisualTool(_parent)
VisualToolDrag::VisualToolDrag(VideoDisplay *parent, VideoState const& video, wxToolBar * toolBar)
: 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);
ConnectButton(toggleMove);
toolBar->AddControl(toggleMove);
toggleMoveOnMove = true;
//UpdateToggleButtons();
toolBar->Realize();
toolBar->Show(true);
}
@ -122,10 +119,12 @@ void VisualToolDrag::OnButton(wxCommandEvent &event) {
bool hasMove;
GetLinePosition(line,x1,y1);
GetLineMove(line,hasMove,x1,y1,x2,y2,t1,t2);
parent->ToScriptCoords(&x1, &y1);
parent->ToScriptCoords(&x2, &y2);
// Replace tag
if (hasMove) SetOverride(_T("\\pos"),wxString::Format(_T("(%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()));
if (hasMove) SetOverride(L"\\pos",wxString::Format(L"(%i,%i)",x1,y1));
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;
grid->editBox->CommitText();
grid->ass->FlagAsModified(_("visual typesetting"));
@ -144,16 +143,6 @@ void VisualToolDrag::DoRefresh() {
UpdateToggleButtons();
}
/// @brief Update
///
void VisualToolDrag::Update() {
GetParent()->Render();
}
/// @brief Draw
///
void VisualToolDrag::Draw() {
@ -289,16 +278,6 @@ void VisualToolDrag::PopulateFeatureList() {
}
}
/// @brief Start dragging
/// @param feature
///
void VisualToolDrag::InitializeDrag(VisualDraggableFeature &feature) {
}
/// @brief Update drag
/// @param feature
///
@ -316,12 +295,18 @@ void VisualToolDrag::UpdateDrag(VisualDraggableFeature &feature) {
void VisualToolDrag::CommitDrag(VisualDraggableFeature &feature) {
// Origin
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
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
@ -332,8 +317,15 @@ void VisualToolDrag::CommitDrag(VisualDraggableFeature &feature) {
if (p1->type == DRAG_BIG_CIRCLE) p1 = &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
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; }
void PopulateFeatureList();
void InitializeDrag(VisualDraggableFeature &feature);
void UpdateDrag(VisualDraggableFeature &feature);
void CommitDrag(VisualDraggableFeature &feature);
@ -75,10 +74,7 @@ private:
void DoRefresh();
public:
VisualToolDrag(VideoDisplay *parent,wxToolBar *toolbar);
VisualToolDrag(VideoDisplay *parent, VideoState const& video, wxToolBar *toolbar);
void Update();
void Draw();
};

View file

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

View file

@ -51,27 +51,13 @@
/// @brief Constructor
/// @param _parent
///
VisualToolRotateZ::VisualToolRotateZ(VideoDisplay *_parent)
: VisualTool(_parent)
VisualToolRotateZ::VisualToolRotateZ(VideoDisplay *parent, VideoState const& video, wxToolBar *)
: VisualTool(parent, video)
{
_parent->ShowCursor(false);
DoRefresh();
}
/// @brief Update
///
void VisualToolRotateZ::Update() {
// Render parent
GetParent()->Render();
}
/// @brief Draw
/// @return
///
void VisualToolRotateZ::Draw() {
// Get line to draw
AssDialogue *line = GetActiveDialogueLine();
@ -162,7 +148,7 @@ void VisualToolRotateZ::Draw() {
// Draw line to mouse
if (!dragging && GetHighlightedFeature() == -1) {
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() {
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);
curAngle = origAngle;
curDiag->StripTag(_T("\\frz"));
curDiag->StripTag(_T("\\fr"));
curDiag->StripTag(L"\\frz");
curDiag->StripTag(L"\\fr");
}
@ -185,7 +171,7 @@ void VisualToolRotateZ::InitializeHold() {
///
void VisualToolRotateZ::UpdateHold() {
// 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;
while (curAngle < 0.0f) curAngle += 360.0f;
while (curAngle >= 360.0f) curAngle -= 360.0f;
@ -202,7 +188,7 @@ void VisualToolRotateZ::UpdateHold() {
/// @brief Commit hold
///
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
///
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
///
///////////
// Headers
#include "visual_tool.h"
@ -91,10 +86,7 @@ private:
void DoRefresh();
public:
VisualToolRotateZ(VideoDisplay *parent);
VisualToolRotateZ(VideoDisplay *parent, VideoState const& video, wxToolBar *);
void Update();
void Draw();
};

View file

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

View file

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

View file

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

View file

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