Re-implemented z rotation on visual typesetting

Originally committed to SVN as r1326.
This commit is contained in:
Rodrigo Braz Monteiro 2007-07-01 02:23:57 +00:00
parent 48db3ab310
commit a1050db3f3
9 changed files with 399 additions and 43 deletions

View File

@ -216,6 +216,7 @@ aegisub_SOURCES = \
visual_feature.cpp \
visual_tool.cpp \
visual_tool_cross.cpp \
visual_tool_rotatez.cpp \
MatroskaParser.c
noinst_HEADERS = \

View File

@ -83,7 +83,6 @@ AudioKaraoke::AudioKaraoke(wxWindow *parent)
//////////////
// Destructor
AudioKaraoke::~AudioKaraoke() {
wxLogDebug(_T("AudioKaraoke destructor"));
delete workDiag;
}

View File

@ -81,11 +81,13 @@ PFNGLUNIFORM2FARBPROC glUniform2fARB = NULL;
#endif
////////////////
// GLEW library
//#if __VISUALC__ >= 1200
//#pragma comment(lib,"glew32.lib")
//#endif
///////////////
// Constructor
OpenGLWrapper::OpenGLWrapper() {
r1 = g1 = b1 = a1 = 1.0f;
r2 = g2 = b2 = a2 = 1.0f;
lw = 1;
}
/////////////

View File

@ -45,13 +45,14 @@ private:
float r2,g2,b2,a2;
int lw;
static void Initialize();
static GLuint CreateStandardVertexShader();
static GLuint CreateYV12PixelShader();
static GLuint CreateShaderProgram(GLuint vertex,GLuint pixel);
public:
OpenGLWrapper();
static wxMutex glMutex;
void SetLineColour(wxColour col,float alpha=1.0f,int width=1);

View File

@ -69,6 +69,7 @@
#include "gl_wrap.h"
#include "visual_tool.h"
#include "visual_tool_cross.h"
#include "visual_tool_rotatez.h"
///////
@ -645,6 +646,11 @@ void VideoDisplay::SetVisualMode(int mode) {
delete visual;
switch (mode) {
case 0: visual = new VisualToolCross(this); break;
//case 1: visual = new VisualToolDrag(this); 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;
default: visual = NULL;
}

View File

@ -63,6 +63,9 @@ VisualTool::VisualTool(VideoDisplay *par) {
colour[1] = wxColour(166,247,177);
colour[2] = wxColour(255,255,255);
colour[3] = wxColour(187,0,0);
holding = false;
curDiag = NULL;
}
@ -72,6 +75,111 @@ VisualTool::~VisualTool() {
}
///////////////
// Mouse event
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();
SubtitlesGrid *grid = VideoContext::Get()->grid;
bool realTime = Options.AsBool(_T("Video Visual Realtime"));
// Mouse leaving control
if (event.Leaving()) {
mouseX = -1;
mouseY = -1;
}
// Transformed mouse x/y
mx = mouseX * sw / w;
my = mouseY * sh / h;
// Clicks
leftClick = event.ButtonDown(wxMOUSE_BTN_LEFT);
leftDClick = event.LeftDClick();
shiftDown = event.m_shiftDown;
ctrlDown = event.m_controlDown;
altDown = event.m_altDown;
// Hold
if (CanHold()) {
// Start holding
if (!holding && event.LeftIsDown()) {
// Get a dialogue
curDiag = GetActiveDialogueLine();
if (curDiag) {
// Initialize Drag
InitializeHold();
// Set flags
holding = true;
parent->CaptureMouse();
if (realTime) AssLimitToVisibleFilter::SetFrame(frame_n);
}
}
if (holding) {
// Holding
if (event.LeftIsDown()) {
// Update drag
UpdateHold();
if (realTime) {
// Commit
CommitHold();
grid->editBox->CommitText(true);
grid->CommitChanges(false,true);
}
}
// Release
else {
// Disable limiting
if (realTime) AssLimitToVisibleFilter::SetFrame(-1);
// Commit
CommitHold();
grid->editBox->CommitText();
grid->ass->FlagAsModified(_("visual typesetting"));
grid->CommitChanges(false,true);
// Clean up
holding = false;
curDiag = NULL;
parent->ReleaseMouse();
parent->SetFocus();
}
}
}
// Update
Update();
}
////////////////////////////
// Get active dialogue line
AssDialogue* VisualTool::GetActiveDialogueLine() {
SubtitlesGrid *grid = VideoContext::Get()->grid;
AssDialogue *diag = grid->GetDialogue(grid->editBox->linen);
// Check if it's within range
if (diag) {
int f1 = VFR_Output.GetFrameAtTime(diag->Start.GetMS(),true);
int f2 = VFR_Output.GetFrameAtTime(diag->End.GetMS(),false);
// Invisible
if (f1 > frame_n || f2 < frame_n) return NULL;
}
return diag;
}
////////////////////////
// Get position of line
void VisualTool::GetLinePosition(AssDialogue *diag,int &x, int &y) {
@ -300,39 +408,3 @@ void VisualTool::GetLineClip(AssDialogue *diag,int &x1,int &y1,int &x2,int &y2)
}
diag->ClearBlocks();
}
///////////////
// Mouse event
void VisualTool::OnMouseEvent (wxMouseEvent &event) {
// Coords
int x = event.GetX();
int y = event.GetY();
parent->ConvertMouseCoords(x,y);
parent->GetClientSize(&w,&h);
VideoContext::Get()->GetScriptSize(sw,sh);
frame_n = VideoContext::Get()->GetFrameN();
// Hover
if (x != mouseX || y != mouseY) {
mouseX = x;
mouseY = y;
}
// Mouse leaving control
if (event.Leaving()) {
mouseX = -1;
mouseY = -1;
}
// Transformed mouse x/y
mx = mouseX * sw / w;
my = mouseY * sh / h;
// Clicks
leftClick = event.ButtonDown(wxMOUSE_BTN_LEFT);
leftDClick = event.LeftDClick();
// Update
Update();
}

View File

@ -58,11 +58,17 @@ private:
protected:
wxColour colour[4];
bool holding;
AssDialogue *curDiag;
int w,h,sw,sh,mx,my;
int frame_n;
bool leftClick;
bool leftDClick;
bool shiftDown;
bool ctrlDown;
bool altDown;
void GetLinePosition(AssDialogue *diag,int &x,int &y);
void GetLinePosition(AssDialogue *diag,int &x,int &y,int &orgx,int &orgy);
@ -73,6 +79,12 @@ protected:
VideoDisplay *GetParent() { return parent; }
virtual AssDialogue *GetActiveDialogueLine();
virtual bool CanHold() { return false; }
virtual void InitializeHold() {}
virtual void UpdateHold() {}
virtual void CommitHold() {}
public:
int mouseX,mouseY;

View File

@ -0,0 +1,200 @@
// Copyright (c) 2007, Rodrigo Braz Monteiro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Aegisub Group nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------------
//
// AEGISUB
//
// Website: http://aegisub.cellosoft.com
// Contact: mailto:zeratul@cellosoft.com
//
#pragma once
///////////
// Headers
#include "visual_tool_rotatez.h"
#include "gl_text.h"
#include "subs_grid.h"
#include "subs_edit_box.h"
#include "ass_file.h"
#include "ass_dialogue.h"
#include "utils.h"
///////////////
// Constructor
VisualToolRotateZ::VisualToolRotateZ(VideoDisplay *_parent)
: VisualTool(_parent)
{
_parent->ShowCursor(false);
}
//////////
// Update
void VisualToolRotateZ::Update() {
// Render parent
GetParent()->Render();
}
////////
// Draw
void VisualToolRotateZ::Draw() {
// Get line to draw
AssDialogue *line = GetActiveDialogueLine();
if (!line) return;
// Radius
int dx=0,dy=0;
GetLinePosition(line,dx,dy,orgx,orgy);
int radius = (int) sqrt(double((dx-orgx)*(dx-orgx)+(dy-orgy)*(dy-orgy)));
int oRadius = radius;
if (radius < 50) radius = 50;
// Pivot coordinates
int odx = dx;
int ody = dy;
dx = orgx;
dy = orgy;
// Rotation
float rz;
GetLineRotation(line,rx,ry,rz);
if (line == curDiag) rz = curAngle;
// Get scale
float scalX = 100.0f;
float scalY = 100.0f;
GetLineScale(line,scalX,scalY);
// Get deltas
int deltax = int(cos(rz*3.1415926536/180.0)*radius);
int deltay = int(-sin(rz*3.1415926536/180.0)*radius);
// Set colours
SetLineColour(colour[0]);
SetFillColour(colour[1],0.3f);
// Draw pivot
DrawCircle(dx,dy,7);
DrawLine(dx,dy-16,dx,dy+16);
DrawLine(dx-16,dy,dx+16,dy);
// Set up the projection
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
glTranslatef(dx,dy,-1.0f);
float matrix[16] = { 2500, 0, 0, 0, 0, 2500, 0, 0, 0, 0, 1, 1, 0, 0, 2500, 2500 };
glMultMatrixf(matrix);
glScalef(1.0f,1.0f,8.0f);
glRotatef(ry,0.0f,-1.0f,0.0f);
glRotatef(rx,-1.0f,0.0f,0.0f);
glScalef(scalX/100.0f,scalY/100.0f,1.0f);
// Draw the circle
DrawRing(0,0,radius+4,radius-4);
// Draw markers around circle
int markers = 6;
float markStart = -90.0f / markers;
float markEnd = markStart+(180.0f/markers);
for (int i=0;i<markers;i++) {
float angle = i*(360.0f/markers);
DrawRing(0,0,radius+30,radius+12,radius/radius,angle+markStart,angle+markEnd);
}
// Draw the baseline
SetLineColour(colour[3],1.0f,2);
DrawLine(deltax,deltay,-deltax,-deltay);
// Draw the connection line
if (orgx != odx && orgy != ody) {
double angle = atan2(double(dy-ody),double(odx-dx)) + rz*3.1415926536/180.0;
int fx = int(cos(angle)*oRadius);
int fy = -int(sin(angle)*oRadius);
DrawLine(0,0,fx,fy);
int mdx = int(cos(rz*3.1415926536/180.0)*20);
int mdy = int(-sin(rz*3.1415926536/180.0)*20);
DrawLine(-mdx,-mdy,mdx,mdy);
}
// Draw the rotation line
SetLineColour(colour[0],1.0f,1);
SetFillColour(colour[1],0.3f);
DrawCircle(deltax,deltay,4);
// Restore
glPopMatrix();
// Draw line to mouse
if (mouseX != -1) {
SetLineColour(colour[0]);
DrawLine(dx,dy,mx,my);
}
}
/////////////////
// Start holding
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;
GetLineRotation(curDiag,rx,ry,origAngle);
curAngle = origAngle;
curDiag->StripTag(_T("\\frz"));
curDiag->StripTag(_T("\\fr"));
}
///////////////
// Update hold
void VisualToolRotateZ::UpdateHold() {
// Find angle
float screenAngle = atan2(double(orgy-mouseY*sh/h),double(mouseX*sw/w-orgx)) * 180.0 / 3.1415926535897932;
curAngle = screenAngle - startAngle + origAngle;
while (curAngle < 0.0f) curAngle += 360.0f;
while (curAngle >= 360.0f) curAngle -= 360.0f;
// Snap
if (shiftDown) {
curAngle = (float)((int)((curAngle+15.0f)/30.0f))*30.0f;
if (curAngle == 360.0f) curAngle = 0.0f;
}
}
///////////////
// Commit hold
void VisualToolRotateZ::CommitHold() {
wxString param = PrettyFloat(wxString::Format(_T("(%0.3f)"),curAngle));
VideoContext::Get()->grid->editBox->SetOverride(_T("\\frz"),param,0,false);
}

View File

@ -0,0 +1,63 @@
// Copyright (c) 2007, Rodrigo Braz Monteiro
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice,
// this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright notice,
// this list of conditions and the following disclaimer in the documentation
// and/or other materials provided with the distribution.
// * Neither the name of the Aegisub Group nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// -----------------------------------------------------------------------------
//
// AEGISUB
//
// Website: http://aegisub.cellosoft.com
// Contact: mailto:zeratul@cellosoft.com
//
#pragma once
///////////
// Headers
#include "visual_tool.h"
/////////////////////////
// Z Rotation tool class
class VisualToolRotateZ : public VisualTool {
private:
float curAngle,startAngle,origAngle;
int orgx,orgy,odx,ody;
float rx,ry;
bool CanHold() { return true; }
void InitializeHold();
void UpdateHold();
void CommitHold();
public:
VisualToolRotateZ(VideoDisplay *parent);
void Update();
void Draw();
};