mirror of https://github.com/odrling/Aegisub
Added freehand and smoothed freehand drawing to vector \clip.
Originally committed to SVN as r1386.
This commit is contained in:
parent
5f2508ee70
commit
1af87b0808
|
@ -178,6 +178,7 @@ aegisub_SOURCES = \
|
|||
scintilla_text_ctrl.cpp \
|
||||
spellchecker.cpp \
|
||||
spline.cpp \
|
||||
spline_curve.cpp \
|
||||
standard_paths.cpp \
|
||||
static_bmp.cpp \
|
||||
string_codec.cpp \
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
|
@ -149,6 +149,7 @@ visual_vector_clip_remove BITMAP "bitmaps/visual_vector_clip_remove.bmp"
|
|||
visual_vector_clip_convert BITMAP "bitmaps/visual_vector_clip_convert.bmp"
|
||||
visual_vector_clip_insert BITMAP "bitmaps/visual_vector_clip_insert.bmp"
|
||||
visual_vector_clip_freehand BITMAP "bitmaps/visual_vector_clip_freehand.bmp"
|
||||
visual_vector_clip_freehand_smooth BITMAP "bitmaps/visual_vector_clip_freehand_smooth.bmp"
|
||||
visual_realtime BITMAP "bitmaps/visual_realtime.bmp"
|
||||
|
||||
arrow_up BITMAP "bitmaps/arrow_up.bmp"
|
||||
|
|
|
@ -38,53 +38,7 @@
|
|||
// Headers
|
||||
#include <wx/tokenzr.h>
|
||||
#include "spline.h"
|
||||
|
||||
|
||||
/////////////////////
|
||||
// Curve constructor
|
||||
SplineCurve::SplineCurve() {
|
||||
type = CURVE_INVALID;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
// Split a curve in two using the de Casteljau algorithm
|
||||
void SplineCurve::Split(SplineCurve &c1,SplineCurve &c2,float t) {
|
||||
// Split a line
|
||||
if (type == CURVE_LINE) {
|
||||
c1.type = CURVE_LINE;
|
||||
c2.type = CURVE_LINE;
|
||||
c1.p1 = p1;
|
||||
c1.p2 = p1*t+p2*(1-t);
|
||||
c2.p1 = c1.p2;
|
||||
c2.p2 = p2;
|
||||
}
|
||||
|
||||
// Split a bicubic
|
||||
else if (type == CURVE_BICUBIC) {
|
||||
c1.type = CURVE_BICUBIC;
|
||||
c2.type = CURVE_BICUBIC;
|
||||
|
||||
// Sub-divisions
|
||||
float u = 1-t;
|
||||
Vector2D p12 = p1*t+p2*u;
|
||||
Vector2D p23 = p2*t+p3*u;
|
||||
Vector2D p34 = p3*t+p4*u;
|
||||
Vector2D p123 = p12*t+p23*u;
|
||||
Vector2D p234 = p23*t+p34*u;
|
||||
Vector2D p1234 = p123*t+p234*u;
|
||||
|
||||
// Set points
|
||||
c1.p1 = p1;
|
||||
c1.p2 = p12;
|
||||
c1.p3 = p123;
|
||||
c1.p4 = p1234;
|
||||
c2.p1 = p1234;
|
||||
c2.p2 = p234;
|
||||
c2.p3 = p34;
|
||||
c2.p4 = p4;
|
||||
}
|
||||
}
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
//////////////////////
|
||||
|
@ -362,3 +316,27 @@ Vector2D Spline::GetClosestControlPoint(Vector2D reference) {
|
|||
// TODO
|
||||
return Vector2D(-1,-1);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////
|
||||
// Smoothes the spline
|
||||
void Spline::Smooth(float smooth) {
|
||||
// See if there are enough curves
|
||||
if (curves.size() < 3) return;
|
||||
|
||||
// Smooth curve
|
||||
SplineCurve *curve0 = NULL;
|
||||
SplineCurve *curve1 = &curves.back();
|
||||
SplineCurve *curve2 = NULL;
|
||||
for (std::list<SplineCurve>::iterator cur=curves.begin();cur!=curves.end();) {
|
||||
// Get curves
|
||||
curve0 = curve1;
|
||||
curve1 = &(*cur);
|
||||
cur++;
|
||||
if (cur == curves.end()) curve2 = &curves.front();
|
||||
else curve2 = &(*cur);
|
||||
|
||||
// Smooth curve
|
||||
curve1->Smooth(curve0->p1,curve2->p2,smooth);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -42,29 +42,7 @@
|
|||
#include <wx/wxprec.h>
|
||||
#include <list>
|
||||
#include <vector>
|
||||
#include "vector2d.h"
|
||||
|
||||
|
||||
///////////////
|
||||
// Curve types
|
||||
enum CurveType {
|
||||
CURVE_INVALID,
|
||||
CURVE_POINT,
|
||||
CURVE_LINE,
|
||||
CURVE_BICUBIC
|
||||
};
|
||||
|
||||
|
||||
////////////////
|
||||
// Spline curve
|
||||
class SplineCurve {
|
||||
public:
|
||||
Vector2D p1,p2,p3,p4;
|
||||
CurveType type;
|
||||
|
||||
SplineCurve();
|
||||
void Split(SplineCurve &c1,SplineCurve &c2,float t=0.5);
|
||||
};
|
||||
#include "spline_curve.h"
|
||||
|
||||
|
||||
/////////////////////////
|
||||
|
@ -80,6 +58,7 @@ public:
|
|||
|
||||
void AppendCurve(SplineCurve &curve);
|
||||
void MovePoint(int curveIndex,int point,wxPoint pos);
|
||||
void Smooth(float smooth=1.0f);
|
||||
|
||||
void GetPointList(std::vector<Vector2D> &points);
|
||||
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
// 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
|
||||
//
|
||||
|
||||
|
||||
///////////
|
||||
// Headers
|
||||
#include "spline_curve.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
/////////////////////
|
||||
// Curve constructor
|
||||
SplineCurve::SplineCurve() {
|
||||
type = CURVE_INVALID;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
// Split a curve in two using the de Casteljau algorithm
|
||||
void SplineCurve::Split(SplineCurve &c1,SplineCurve &c2,float t) {
|
||||
// Split a line
|
||||
if (type == CURVE_LINE) {
|
||||
c1.type = CURVE_LINE;
|
||||
c2.type = CURVE_LINE;
|
||||
c1.p1 = p1;
|
||||
c1.p2 = p1*t+p2*(1-t);
|
||||
c2.p1 = c1.p2;
|
||||
c2.p2 = p2;
|
||||
}
|
||||
|
||||
// Split a bicubic
|
||||
else if (type == CURVE_BICUBIC) {
|
||||
c1.type = CURVE_BICUBIC;
|
||||
c2.type = CURVE_BICUBIC;
|
||||
|
||||
// Sub-divisions
|
||||
float u = 1-t;
|
||||
Vector2D p12 = p1*t+p2*u;
|
||||
Vector2D p23 = p2*t+p3*u;
|
||||
Vector2D p34 = p3*t+p4*u;
|
||||
Vector2D p123 = p12*t+p23*u;
|
||||
Vector2D p234 = p23*t+p34*u;
|
||||
Vector2D p1234 = p123*t+p234*u;
|
||||
|
||||
// Set points
|
||||
c1.p1 = p1;
|
||||
c1.p2 = p12;
|
||||
c1.p3 = p123;
|
||||
c1.p4 = p1234;
|
||||
c2.p1 = p1234;
|
||||
c2.p2 = p234;
|
||||
c2.p3 = p34;
|
||||
c2.p4 = p4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////
|
||||
// Smoothes the curve
|
||||
// Based on http://antigrain.com/research/bezier_interpolation/index.html
|
||||
void SplineCurve::Smooth(Vector2D P0,Vector2D P3,float smooth) {
|
||||
// Validate
|
||||
if (type != CURVE_LINE) return;
|
||||
smooth = MID(0.0f,smooth,1.0f);
|
||||
|
||||
// Get points
|
||||
Vector2D P1 = p1;
|
||||
Vector2D P2 = p2;
|
||||
|
||||
// Calculate intermediate points
|
||||
Vector2D c1 = (P0+P1)/2.0f;
|
||||
Vector2D c2 = (P1+P2)/2.0f;
|
||||
Vector2D c3 = (P2+P3)/2.0f;
|
||||
float len1 = (P1-P0).Len();
|
||||
float len2 = (P2-P1).Len();
|
||||
float len3 = (P3-P2).Len();
|
||||
float k1 = len1/(len1+len2);
|
||||
float k2 = len2/(len2+len3);
|
||||
Vector2D m1 = c1+(c2-c1)*k1;
|
||||
Vector2D m2 = c2+(c3-c2)*k2;
|
||||
|
||||
// Set curve points
|
||||
p4 = p2;
|
||||
p2 = m1+(c2-m1)*smooth + P1 - m1;
|
||||
p3 = m2+(c2-m2)*smooth + P2 - m2;
|
||||
type = CURVE_BICUBIC;
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
// 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 "vector2d.h"
|
||||
|
||||
|
||||
///////////////
|
||||
// Curve types
|
||||
enum CurveType {
|
||||
CURVE_INVALID,
|
||||
CURVE_POINT,
|
||||
CURVE_LINE,
|
||||
CURVE_BICUBIC
|
||||
};
|
||||
|
||||
|
||||
////////////////
|
||||
// Spline curve
|
||||
class SplineCurve {
|
||||
public:
|
||||
Vector2D p1,p2,p3,p4;
|
||||
CurveType type;
|
||||
|
||||
SplineCurve();
|
||||
void Split(SplineCurve &c1,SplineCurve &c2,float t=0.5);
|
||||
void Smooth(Vector2D prev,Vector2D next,float smooth=1.0f);
|
||||
};
|
|
@ -64,9 +64,10 @@ public:
|
|||
|
||||
Vector2D Unit ();
|
||||
float Cross (const Vector2D param) const;
|
||||
virtual float Dot (const Vector2D param) const;
|
||||
float Dot (const Vector2D param) const;
|
||||
|
||||
virtual float Len () const;
|
||||
float Len () const;
|
||||
float Length () const { return Len(); }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@
|
|||
#include "utils.h"
|
||||
#include "main.h"
|
||||
#include "toggle_bitmap.h"
|
||||
#include "visual_tool.h"
|
||||
|
||||
|
||||
///////////////
|
||||
|
@ -157,6 +158,7 @@ BEGIN_EVENT_TABLE(VideoBox, wxPanel)
|
|||
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)
|
||||
END_EVENT_TABLE()
|
||||
|
||||
|
@ -201,6 +203,13 @@ void VideoBox::OnModeChange(wxCommandEvent &event) {
|
|||
}
|
||||
|
||||
|
||||
///////////////////////////
|
||||
// Sub-tool button pressed
|
||||
void VideoBox::OnSubTool(wxCommandEvent &event) {
|
||||
videoDisplay->visual->OnSubTool(event);
|
||||
}
|
||||
|
||||
|
||||
///////////////////
|
||||
// Realtime toggle
|
||||
void VideoBox::OnToggleRealtime(wxCommandEvent &event) {
|
||||
|
|
|
@ -34,8 +34,7 @@
|
|||
//
|
||||
|
||||
|
||||
#ifndef VIDEO_BOX_H
|
||||
#define VIDEO_BOX_H
|
||||
#pragma once
|
||||
|
||||
|
||||
///////////
|
||||
|
@ -62,6 +61,7 @@ private:
|
|||
void OnVideoToggleScroll(wxCommandEvent &event);
|
||||
|
||||
void OnModeChange(wxCommandEvent &event);
|
||||
void OnSubTool(wxCommandEvent &event);
|
||||
void OnToggleRealtime(wxCommandEvent &event);
|
||||
|
||||
public:
|
||||
|
@ -102,5 +102,3 @@ enum {
|
|||
Video_Mode_Vector_Clip,
|
||||
Video_Mode_Realtime,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -132,8 +132,16 @@ void VisualTool::OnMouseEvent (wxMouseEvent &event) {
|
|||
dragListOK = true;
|
||||
}
|
||||
|
||||
// Click on feature
|
||||
if (!dragging && leftClick && !DragEnabled()) {
|
||||
curFeature = GetHighlightedFeature();
|
||||
if (curFeature != -1) {
|
||||
ClickedFeature(features[curFeature]);
|
||||
}
|
||||
}
|
||||
|
||||
// Start dragging
|
||||
if (!dragging && leftClick) {
|
||||
if (!dragging && leftClick && DragEnabled()) {
|
||||
// Get a feature
|
||||
curFeature = GetHighlightedFeature();
|
||||
if (curFeature != -1) {
|
||||
|
@ -178,13 +186,13 @@ void VisualTool::OnMouseEvent (wxMouseEvent &event) {
|
|||
if (realTime) AssLimitToVisibleFilter::SetFrame(-1);
|
||||
|
||||
// Commit
|
||||
dragging = false;
|
||||
CommitDrag(features[curFeature]);
|
||||
grid->editBox->CommitText();
|
||||
grid->ass->FlagAsModified(_("visual typesetting"));
|
||||
grid->CommitChanges(false);
|
||||
|
||||
// Clean up
|
||||
dragging = false;
|
||||
curFeature = -1;
|
||||
parent->ReleaseMouse();
|
||||
parent->SetFocus();
|
||||
|
@ -196,7 +204,7 @@ void VisualTool::OnMouseEvent (wxMouseEvent &event) {
|
|||
// Hold
|
||||
if (!dragging && CanHold()) {
|
||||
// Start holding
|
||||
if (!holding && event.LeftIsDown()) {
|
||||
if (!holding && event.LeftIsDown() && HoldEnabled()) {
|
||||
// Get a dialogue
|
||||
curDiag = GetActiveDialogueLine();
|
||||
if (curDiag) {
|
||||
|
@ -230,13 +238,13 @@ void VisualTool::OnMouseEvent (wxMouseEvent &event) {
|
|||
if (realTime) AssLimitToVisibleFilter::SetFrame(-1);
|
||||
|
||||
// Commit
|
||||
holding = false;
|
||||
CommitHold();
|
||||
grid->editBox->CommitText();
|
||||
grid->ass->FlagAsModified(_("visual typesetting"));
|
||||
grid->CommitChanges(false);
|
||||
|
||||
// Clean up
|
||||
holding = false;
|
||||
curDiag = NULL;
|
||||
parent->ReleaseMouse();
|
||||
parent->SetFocus();
|
||||
|
|
|
@ -52,6 +52,12 @@ class AssDialogue;
|
|||
class VisualTool;
|
||||
|
||||
|
||||
/////////////////////////
|
||||
// Visual sub tool range
|
||||
#define VISUAL_SUB_TOOL_START 1300
|
||||
#define VISUAL_SUB_TOOL_END (VISUAL_SUB_TOOL_START+100)
|
||||
|
||||
|
||||
////////////////////
|
||||
// Event sink class
|
||||
class VisualToolEvent : public wxEvtHandler {
|
||||
|
@ -114,15 +120,18 @@ protected:
|
|||
virtual void OnButton(wxCommandEvent &event) {}
|
||||
|
||||
virtual bool CanHold() { return false; }
|
||||
virtual bool HoldEnabled() { return true; }
|
||||
virtual void InitializeHold() {}
|
||||
virtual void UpdateHold() {}
|
||||
virtual void CommitHold() {}
|
||||
|
||||
virtual bool CanDrag() { return false; }
|
||||
virtual bool DragEnabled() { return true; }
|
||||
virtual void PopulateFeatureList() { wxLogMessage(_T("wtf?")); }
|
||||
virtual void InitializeDrag(VisualDraggableFeature &feature) {}
|
||||
virtual void UpdateDrag(VisualDraggableFeature &feature) {}
|
||||
virtual void CommitDrag(VisualDraggableFeature &feature) {}
|
||||
virtual void ClickedFeature(VisualDraggableFeature &feature) {}
|
||||
|
||||
virtual void DoRefresh() {}
|
||||
|
||||
|
@ -130,6 +139,7 @@ public:
|
|||
int mouseX,mouseY;
|
||||
|
||||
void OnMouseEvent(wxMouseEvent &event);
|
||||
virtual void OnSubTool(wxCommandEvent &event) {}
|
||||
virtual void Update()=0;
|
||||
virtual void Draw()=0;
|
||||
void Refresh();
|
||||
|
|
|
@ -51,7 +51,7 @@
|
|||
///////
|
||||
// IDs
|
||||
enum {
|
||||
BUTTON_TOGGLE_MOVE = 1300
|
||||
BUTTON_TOGGLE_MOVE = VISUAL_SUB_TOOL_START
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -43,24 +43,28 @@
|
|||
///////
|
||||
// IDs
|
||||
enum {
|
||||
BUTTON_DRAG = 1300,
|
||||
BUTTON_DRAG = VISUAL_SUB_TOOL_START,
|
||||
BUTTON_LINE,
|
||||
BUTTON_BICUBIC,
|
||||
BUTTON_INSERT,
|
||||
BUTTON_REMOVE,
|
||||
BUTTON_CONVERT,
|
||||
BUTTON_FREEHAND
|
||||
BUTTON_FREEHAND,
|
||||
BUTTON_FREEHAND_SMOOTH,
|
||||
BUTTON_LAST // Leave this at the end and don't use it
|
||||
};
|
||||
|
||||
|
||||
///////////////
|
||||
// Constructor
|
||||
VisualToolVectorClip::VisualToolVectorClip(VideoDisplay *parent,wxToolBar *toolBar)
|
||||
VisualToolVectorClip::VisualToolVectorClip(VideoDisplay *parent,wxToolBar *_toolBar)
|
||||
: VisualTool(parent)
|
||||
{
|
||||
DoRefresh();
|
||||
mode = 0;
|
||||
|
||||
// Create toolbar
|
||||
toolBar = _toolBar;
|
||||
toolBar->AddTool(BUTTON_DRAG,_("Drag"),wxBITMAP(visual_vector_clip_drag),_("Drag control points."),wxITEM_CHECK);
|
||||
toolBar->AddTool(BUTTON_LINE,_("Line"),wxBITMAP(visual_vector_clip_line),_("Appends a line."),wxITEM_CHECK);
|
||||
toolBar->AddTool(BUTTON_BICUBIC,_("Bicubic"),wxBITMAP(visual_vector_clip_bicubic),_("Appends a bezier bicubic curve."),wxITEM_CHECK);
|
||||
|
@ -70,11 +74,31 @@ VisualToolVectorClip::VisualToolVectorClip(VideoDisplay *parent,wxToolBar *toolB
|
|||
toolBar->AddTool(BUTTON_REMOVE,_("Remove"),wxBITMAP(visual_vector_clip_remove),_("Removes a control point."),wxITEM_CHECK);
|
||||
toolBar->AddSeparator();
|
||||
toolBar->AddTool(BUTTON_FREEHAND,_("Freehand"),wxBITMAP(visual_vector_clip_freehand),_("Draws a freehand shape."),wxITEM_CHECK);
|
||||
toolBar->AddTool(BUTTON_FREEHAND_SMOOTH,_("Freehand smooth"),wxBITMAP(visual_vector_clip_freehand_smooth),_("Draws a smoothed freehand shape."),wxITEM_CHECK);
|
||||
toolBar->ToggleTool(BUTTON_DRAG,true);
|
||||
toolBar->Realize();
|
||||
toolBar->Show(true);
|
||||
}
|
||||
|
||||
|
||||
////////////////////
|
||||
// Sub-tool pressed
|
||||
void VisualToolVectorClip::OnSubTool(wxCommandEvent &event) {
|
||||
// Make sure clicked is checked and everything else isn't. (Yes, this is radio behavior, but the separators won't let me use it)
|
||||
for (int i=BUTTON_DRAG;i<BUTTON_LAST;i++) {
|
||||
toolBar->ToggleTool(i,i == event.GetId());
|
||||
}
|
||||
SetMode(event.GetId() - BUTTON_DRAG);
|
||||
}
|
||||
|
||||
|
||||
////////////
|
||||
// Set mode
|
||||
void VisualToolVectorClip::SetMode(int _mode) {
|
||||
mode = _mode;
|
||||
}
|
||||
|
||||
|
||||
//////////
|
||||
// Update
|
||||
void VisualToolVectorClip::Update() {
|
||||
|
@ -96,8 +120,8 @@ void VisualToolVectorClip::Draw() {
|
|||
// Draw lines
|
||||
SetLineColour(colour[3],1.0f,2);
|
||||
SetFillColour(colour[3],0.0f);
|
||||
for (int i=0;i<((signed)points.size())-1;i++) {
|
||||
DrawLine(points[i].x,points[i].y,points[i+1].x,points[i+1].y);
|
||||
for (size_t i=1;i<points.size();i++) {
|
||||
DrawLine(points[i-1].x,points[i-1].y,points[i].x,points[i].y);
|
||||
}
|
||||
|
||||
// Draw stencil mask
|
||||
|
@ -105,11 +129,11 @@ void VisualToolVectorClip::Draw() {
|
|||
glColorMask(0,0,0,0);
|
||||
glStencilFunc(GL_NEVER,1,1);
|
||||
glStencilOp(GL_INVERT,GL_INVERT,GL_INVERT);
|
||||
for (int i=0;i<((signed)points.size())-1;i++) {
|
||||
for (size_t i=2;i<points.size();i++) {
|
||||
glBegin(GL_TRIANGLES);
|
||||
glVertex2f(points[0].x,points[0].y);
|
||||
glVertex2f(points[i-1].x,points[i-1].y);
|
||||
glVertex2f(points[i].x,points[i].y);
|
||||
glVertex2f(points[i+1].x,points[i+1].y);
|
||||
glEnd();
|
||||
}
|
||||
|
||||
|
@ -198,6 +222,13 @@ void VisualToolVectorClip::PopulateFeatureList() {
|
|||
}
|
||||
|
||||
|
||||
/////////////
|
||||
// Can drag?
|
||||
bool VisualToolVectorClip::DragEnabled() {
|
||||
return mode == 0;
|
||||
}
|
||||
|
||||
|
||||
//////////
|
||||
// Update
|
||||
void VisualToolVectorClip::UpdateDrag(VisualDraggableFeature &feature) {
|
||||
|
@ -212,6 +243,61 @@ void VisualToolVectorClip::CommitDrag(VisualDraggableFeature &feature) {
|
|||
}
|
||||
|
||||
|
||||
/////////////////////
|
||||
// Clicked a feature
|
||||
void VisualToolVectorClip::ClickedFeature(VisualDraggableFeature &feature) {
|
||||
}
|
||||
|
||||
|
||||
/////////////
|
||||
// Can hold?
|
||||
bool VisualToolVectorClip::HoldEnabled() {
|
||||
return mode == 6 || mode == 7;
|
||||
}
|
||||
|
||||
|
||||
///////////////////
|
||||
// Initialize hold
|
||||
void VisualToolVectorClip::InitializeHold() {
|
||||
spline.curves.clear();
|
||||
lastX = -100000;
|
||||
lastY = -100000;
|
||||
}
|
||||
|
||||
|
||||
///////////////
|
||||
// Update hold
|
||||
void VisualToolVectorClip::UpdateHold() {
|
||||
if (lastX != -100000 && lastY != -100000) {
|
||||
// See if distance is enough
|
||||
Vector2D delta(lastX-mx,lastY-my);
|
||||
int len = (int)delta.Len();
|
||||
if (mode == 6 && len < 30) return;
|
||||
if (mode == 7 && len < 60) return;
|
||||
|
||||
// Generate curve and add it
|
||||
SplineCurve curve;
|
||||
curve.type = CURVE_LINE;
|
||||
curve.p1 = Vector2D(lastX,lastY);
|
||||
curve.p2 = Vector2D(mx,my);
|
||||
spline.AppendCurve(curve);
|
||||
}
|
||||
lastX = mx;
|
||||
lastY = my;
|
||||
}
|
||||
|
||||
|
||||
///////////////
|
||||
// Commit hold
|
||||
void VisualToolVectorClip::CommitHold() {
|
||||
// Smooth spline
|
||||
if (!holding && mode == 7) spline.Smooth();
|
||||
|
||||
// Save it
|
||||
SetOverride(_T("\\clip"),_T("(") + spline.EncodeToASS() + _T(")"));
|
||||
}
|
||||
|
||||
|
||||
///////////
|
||||
// Refresh
|
||||
void VisualToolVectorClip::DoRefresh() {
|
||||
|
|
|
@ -48,13 +48,27 @@
|
|||
class VisualToolVectorClip : public VisualTool {
|
||||
private:
|
||||
Spline spline;
|
||||
wxToolBar *toolBar;
|
||||
int mode;
|
||||
int lastX,lastY;
|
||||
|
||||
void SetMode(int mode);
|
||||
|
||||
bool CanHold() { return true; }
|
||||
bool HoldEnabled();
|
||||
void InitializeHold();
|
||||
void UpdateHold();
|
||||
void CommitHold();
|
||||
|
||||
bool CanDrag() { return true; }
|
||||
bool DragEnabled();
|
||||
void PopulateFeatureList();
|
||||
void UpdateDrag(VisualDraggableFeature &feature);
|
||||
void CommitDrag(VisualDraggableFeature &feature);
|
||||
void ClickedFeature(VisualDraggableFeature &feature);
|
||||
|
||||
void DoRefresh();
|
||||
void OnSubTool(wxCommandEvent &event);
|
||||
|
||||
public:
|
||||
VisualToolVectorClip(VideoDisplay *parent,wxToolBar *toolbar);
|
||||
|
|
Loading…
Reference in New Issue