2011-11-06 18:18:20 +01:00
|
|
|
// Copyright (c) 2011, Thomas Goyne <plorkyeran@aegisub.org>
|
2007-07-05 06:32:46 +02:00
|
|
|
//
|
2011-11-06 18:18:20 +01:00
|
|
|
// Permission to use, copy, modify, and distribute this software for any
|
|
|
|
// purpose with or without fee is hereby granted, provided that the above
|
|
|
|
// copyright notice and this permission notice appear in all copies.
|
2007-07-05 06:32:46 +02:00
|
|
|
//
|
2011-11-06 18:18:20 +01:00
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
|
|
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
|
|
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
|
|
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
|
|
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
|
|
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
|
|
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
2007-07-05 06:32:46 +02:00
|
|
|
//
|
2009-07-29 07:43:02 +02:00
|
|
|
// Aegisub Project http://www.aegisub.org/
|
2007-07-05 06:32:46 +02:00
|
|
|
//
|
2009-07-29 07:43:02 +02:00
|
|
|
// $Id$
|
|
|
|
|
|
|
|
/// @file visual_tool_vector_clip.cpp
|
|
|
|
/// @brief Vector clipping visual typesetting tool
|
|
|
|
/// @ingroup visual_ts
|
2007-07-05 06:32:46 +02:00
|
|
|
|
2010-08-03 00:14:11 +02:00
|
|
|
#include "visual_tool_vector_clip.h"
|
|
|
|
|
2010-05-16 08:39:11 +02:00
|
|
|
#ifndef AGI_PRE
|
|
|
|
#include <wx/toolbar.h>
|
2010-06-14 21:26:27 +02:00
|
|
|
|
2010-06-24 03:50:16 +02:00
|
|
|
#include <algorithm>
|
2010-06-14 21:26:27 +02:00
|
|
|
#endif
|
|
|
|
|
2009-01-04 07:31:48 +01:00
|
|
|
#include "config.h"
|
|
|
|
|
2007-07-05 06:32:46 +02:00
|
|
|
#include "ass_dialogue.h"
|
2009-07-24 02:08:25 +02:00
|
|
|
#include "libresrc/libresrc.h"
|
2010-06-30 08:29:14 +02:00
|
|
|
#include "utils.h"
|
2007-07-05 06:32:46 +02:00
|
|
|
|
2010-06-28 09:13:15 +02:00
|
|
|
/// Button IDs
|
2007-07-05 08:13:22 +02:00
|
|
|
enum {
|
2011-11-06 18:18:20 +01:00
|
|
|
BUTTON_DRAG = 1300,
|
2007-07-05 08:13:22 +02:00
|
|
|
BUTTON_LINE,
|
|
|
|
BUTTON_BICUBIC,
|
2007-07-07 09:27:28 +02:00
|
|
|
BUTTON_CONVERT,
|
2007-07-05 08:13:22 +02:00
|
|
|
BUTTON_INSERT,
|
|
|
|
BUTTON_REMOVE,
|
2007-07-07 07:51:18 +02:00
|
|
|
BUTTON_FREEHAND,
|
|
|
|
BUTTON_FREEHAND_SMOOTH,
|
2010-06-08 08:09:19 +02:00
|
|
|
BUTTON_LAST // Leave this at the end and don't use it
|
2007-07-05 08:13:22 +02:00
|
|
|
};
|
|
|
|
|
2011-11-06 18:18:20 +01:00
|
|
|
VisualToolVectorClip::VisualToolVectorClip(VideoDisplay *parent, agi::Context *context)
|
|
|
|
: VisualTool<VisualToolVectorClipDraggableFeature>(parent, context)
|
|
|
|
, spline(*this)
|
|
|
|
{
|
2010-06-30 08:29:14 +02:00
|
|
|
}
|
|
|
|
|
2011-11-06 18:18:20 +01:00
|
|
|
void VisualToolVectorClip::SetToolbar(wxToolBar *toolBar) {
|
|
|
|
this->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);
|
2007-07-07 05:21:52 +02:00
|
|
|
toolBar->AddSeparator();
|
2011-11-06 18:18:20 +01:00
|
|
|
toolBar->AddTool(BUTTON_CONVERT, _("Convert"), GETIMAGE(visual_vector_clip_convert_24), _("Converts a segment between line and bicubic."), wxITEM_CHECK);
|
|
|
|
toolBar->AddTool(BUTTON_INSERT, _("Insert"), GETIMAGE(visual_vector_clip_insert_24), _("Inserts a control point."), wxITEM_CHECK);
|
|
|
|
toolBar->AddTool(BUTTON_REMOVE, _("Remove"), GETIMAGE(visual_vector_clip_remove_24), _("Removes a control point."), wxITEM_CHECK);
|
2007-07-07 05:21:52 +02:00
|
|
|
toolBar->AddSeparator();
|
2011-11-06 18:18:20 +01:00
|
|
|
toolBar->AddTool(BUTTON_FREEHAND, _("Freehand"), GETIMAGE(visual_vector_clip_freehand_24), _("Draws a freehand shape."), wxITEM_CHECK);
|
|
|
|
toolBar->AddTool(BUTTON_FREEHAND_SMOOTH, _("Freehand smooth"), GETIMAGE(visual_vector_clip_freehand_smooth_24), _("Draws a smoothed freehand shape."), wxITEM_CHECK);
|
|
|
|
toolBar->ToggleTool(BUTTON_DRAG, true);
|
2007-07-07 05:21:52 +02:00
|
|
|
toolBar->Realize();
|
|
|
|
toolBar->Show(true);
|
2011-11-06 18:18:20 +01:00
|
|
|
toolBar->Bind(wxEVT_COMMAND_TOOL_CLICKED, &VisualToolVectorClip::OnSubTool, this);
|
2010-06-28 09:13:15 +02:00
|
|
|
SetMode(features.empty());
|
2007-07-05 06:32:46 +02:00
|
|
|
}
|
|
|
|
|
2007-07-07 07:51:18 +02:00
|
|
|
void VisualToolVectorClip::OnSubTool(wxCommandEvent &event) {
|
|
|
|
SetMode(event.GetId() - BUTTON_DRAG);
|
|
|
|
}
|
|
|
|
|
2011-11-06 18:18:20 +01:00
|
|
|
void VisualToolVectorClip::SetMode(int new_mode) {
|
2010-06-08 08:09:19 +02:00
|
|
|
// Manually enforce radio behavior as we want one selection in the bar
|
|
|
|
// rather than one per group
|
2011-11-06 18:18:20 +01:00
|
|
|
for (int i = BUTTON_DRAG; i < BUTTON_LAST; i++)
|
|
|
|
toolBar->ToggleTool(i, i == new_mode + BUTTON_DRAG);
|
2010-06-08 08:09:19 +02:00
|
|
|
|
2011-11-06 18:18:20 +01:00
|
|
|
mode = new_mode;
|
2007-07-07 07:51:18 +02:00
|
|
|
}
|
|
|
|
|
2010-06-18 09:14:17 +02:00
|
|
|
static bool is_move(SplineCurve const& c) {
|
2011-11-06 18:18:20 +01:00
|
|
|
return c.type == SplineCurve::POINT;
|
2010-06-18 09:14:17 +02:00
|
|
|
}
|
|
|
|
|
2007-07-05 06:32:46 +02:00
|
|
|
void VisualToolVectorClip::Draw() {
|
2011-11-06 18:18:20 +01:00
|
|
|
if (!active_line) return;
|
2010-06-08 08:09:19 +02:00
|
|
|
if (spline.empty()) return;
|
|
|
|
|
2007-07-05 06:32:46 +02:00
|
|
|
// Parse vector
|
2010-06-07 09:24:43 +02:00
|
|
|
std::vector<float> points;
|
2010-06-08 08:09:19 +02:00
|
|
|
std::vector<int> start;
|
|
|
|
std::vector<int> count;
|
|
|
|
|
|
|
|
spline.GetPointList(points, start, count);
|
|
|
|
assert(!start.empty());
|
|
|
|
assert(!count.empty());
|
2011-11-06 18:18:20 +01:00
|
|
|
|
|
|
|
gl.SetLineColour(colour[3], 1.f, 2);
|
|
|
|
gl.SetFillColour(wxColour(0, 0, 0), 0.5f);
|
|
|
|
|
|
|
|
gl.DrawMultiPolygon(points, start, count, video_res, !inverse);
|
2010-06-08 08:09:19 +02:00
|
|
|
|
|
|
|
Vector2D pt;
|
|
|
|
float t;
|
2011-11-06 18:18:20 +01:00
|
|
|
Spline::iterator highlighted_curve;
|
|
|
|
spline.GetClosestParametricPoint(mouse_pos, highlighted_curve, t, pt);
|
2010-06-07 09:24:43 +02:00
|
|
|
|
|
|
|
// Draw highlighted line
|
2011-11-06 18:18:20 +01:00
|
|
|
if ((mode == 3 || mode == 4) && active_feature == features.end() && points.size() > 2) {
|
|
|
|
std::vector<float> highlighted_points;
|
|
|
|
spline.GetPointList(highlighted_points, highlighted_curve);
|
|
|
|
if (!highlighted_points.empty()) {
|
|
|
|
gl.SetLineColour(colour[2], 1.f, 2);
|
|
|
|
gl.DrawLineStrip(2, highlighted_points);
|
2007-07-08 09:22:09 +02:00
|
|
|
}
|
|
|
|
}
|
2007-07-05 06:32:46 +02:00
|
|
|
|
|
|
|
// Draw lines connecting the bicubic features
|
2011-11-06 18:18:20 +01:00
|
|
|
gl.SetLineColour(colour[3], 0.9f, 1);
|
|
|
|
for (Spline::iterator cur = spline.begin(); cur != spline.end(); ++cur) {
|
|
|
|
if (cur->type == SplineCurve::BICUBIC) {
|
|
|
|
gl.DrawDashedLine(cur->p1, cur->p2, 6);
|
|
|
|
gl.DrawDashedLine(cur->p3, cur->p4, 6);
|
2007-07-05 06:32:46 +02:00
|
|
|
}
|
|
|
|
}
|
2007-07-07 08:41:14 +02:00
|
|
|
|
2007-07-08 09:22:09 +02:00
|
|
|
DrawAllFeatures();
|
|
|
|
|
2007-07-07 08:41:14 +02:00
|
|
|
// Draw preview of inserted line
|
|
|
|
if (mode == 1 || mode == 2) {
|
2011-11-06 18:18:20 +01:00
|
|
|
if (spline.size() && mouse_pos) {
|
2010-06-18 09:14:17 +02:00
|
|
|
Spline::reverse_iterator c0 = std::find_if(spline.rbegin(), spline.rend(), is_move);
|
2010-06-08 08:09:19 +02:00
|
|
|
SplineCurve *c1 = &spline.back();
|
2011-11-06 18:18:20 +01:00
|
|
|
gl.DrawDashedLine(mouse_pos, c0->p1, 6);
|
|
|
|
gl.DrawDashedLine(mouse_pos, c1->EndPoint(), 6);
|
2007-07-07 08:41:14 +02:00
|
|
|
}
|
|
|
|
}
|
2007-07-07 10:53:11 +02:00
|
|
|
|
|
|
|
// Draw preview of insert point
|
2011-11-06 18:18:20 +01:00
|
|
|
if (mode == 4)
|
|
|
|
gl.DrawCircle(pt, 4);
|
2007-07-05 06:32:46 +02:00
|
|
|
}
|
|
|
|
|
2010-06-18 09:14:23 +02:00
|
|
|
void VisualToolVectorClip::MakeFeature(Spline::iterator cur) {
|
2010-06-30 08:29:14 +02:00
|
|
|
Feature feat;
|
2011-11-06 18:18:20 +01:00
|
|
|
feat.curve = cur;
|
|
|
|
|
|
|
|
if (cur->type == SplineCurve::POINT) {
|
|
|
|
feat.pos = cur->p1;
|
2010-06-18 09:14:23 +02:00
|
|
|
feat.type = DRAG_SMALL_CIRCLE;
|
|
|
|
feat.point = 0;
|
|
|
|
}
|
2011-11-06 18:18:20 +01:00
|
|
|
else if (cur->type == SplineCurve::LINE) {
|
|
|
|
feat.pos = cur->p2;
|
2010-06-18 09:14:23 +02:00
|
|
|
feat.type = DRAG_SMALL_CIRCLE;
|
|
|
|
feat.point = 1;
|
|
|
|
}
|
2011-11-06 18:18:20 +01:00
|
|
|
else if (cur->type == SplineCurve::BICUBIC) {
|
2010-06-18 09:14:23 +02:00
|
|
|
// Control points
|
2011-11-06 18:18:20 +01:00
|
|
|
feat.pos = cur->p2;
|
2010-06-18 09:14:23 +02:00
|
|
|
feat.point = 1;
|
|
|
|
feat.type = DRAG_SMALL_SQUARE;
|
|
|
|
features.push_back(feat);
|
2010-06-30 08:29:14 +02:00
|
|
|
|
2011-11-06 18:18:20 +01:00
|
|
|
feat.pos = cur->p3;
|
2010-06-18 09:14:23 +02:00
|
|
|
feat.point = 2;
|
|
|
|
features.push_back(feat);
|
|
|
|
|
|
|
|
// End point
|
2011-11-06 18:18:20 +01:00
|
|
|
feat.pos = cur->p4;
|
2010-06-18 09:14:23 +02:00
|
|
|
feat.type = DRAG_SMALL_CIRCLE;
|
|
|
|
feat.point = 3;
|
|
|
|
}
|
2011-11-06 18:18:20 +01:00
|
|
|
features.push_back(feat);
|
2010-06-18 09:14:23 +02:00
|
|
|
}
|
|
|
|
|
2010-06-30 08:29:14 +02:00
|
|
|
void VisualToolVectorClip::MakeFeatures() {
|
2011-11-06 18:18:20 +01:00
|
|
|
sel_features.clear();
|
2007-07-05 06:32:46 +02:00
|
|
|
features.clear();
|
2011-11-06 18:18:20 +01:00
|
|
|
active_feature = features.end();
|
|
|
|
for (Spline::iterator it = spline.begin(); it != spline.end(); ++it)
|
|
|
|
MakeFeature(it);
|
2010-06-30 08:29:14 +02:00
|
|
|
}
|
2007-07-05 06:32:46 +02:00
|
|
|
|
2010-06-30 08:29:14 +02:00
|
|
|
void VisualToolVectorClip::Save() {
|
2011-11-06 18:18:20 +01:00
|
|
|
SetOverride(active_line, inverse ? "\\iclip" : "\\clip", "(" + spline.EncodeToASS() + ")");
|
2007-07-05 06:32:46 +02:00
|
|
|
}
|
|
|
|
|
2010-06-30 08:29:14 +02:00
|
|
|
void VisualToolVectorClip::UpdateDrag(feature_iterator feature) {
|
2011-11-06 18:18:20 +01:00
|
|
|
spline.MovePoint(feature->curve, feature->point, feature->pos);
|
2010-06-30 08:29:14 +02:00
|
|
|
Save();
|
2007-07-05 06:32:46 +02:00
|
|
|
}
|
|
|
|
|
2010-06-30 08:29:14 +02:00
|
|
|
bool VisualToolVectorClip::InitializeDrag(feature_iterator feature) {
|
|
|
|
if (mode != 5) return true;
|
|
|
|
|
2011-11-06 18:18:20 +01:00
|
|
|
if (feature->curve->type == SplineCurve::BICUBIC && (feature->point == 1 || feature->point == 2)) {
|
2010-06-30 08:29:14 +02:00
|
|
|
// Deleting bicubic curve handles, so convert to line
|
2011-11-06 18:18:20 +01:00
|
|
|
feature->curve->type = SplineCurve::LINE;
|
2010-06-30 08:29:14 +02:00
|
|
|
feature->curve->p2 = feature->curve->p4;
|
|
|
|
}
|
|
|
|
else {
|
2010-06-08 08:09:19 +02:00
|
|
|
Spline::iterator next = feature->curve;
|
|
|
|
next++;
|
|
|
|
if (next != spline.end()) {
|
2011-11-06 18:18:20 +01:00
|
|
|
if (feature->curve->type == SplineCurve::POINT) {
|
2010-06-08 08:09:19 +02:00
|
|
|
next->p1 = next->EndPoint();
|
2011-11-06 18:18:20 +01:00
|
|
|
next->type = SplineCurve::POINT;
|
2010-06-08 08:09:19 +02:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
next->p1 = feature->curve->p1;
|
2007-07-07 09:27:28 +02:00
|
|
|
}
|
|
|
|
}
|
2010-06-08 08:09:19 +02:00
|
|
|
|
|
|
|
spline.erase(feature->curve);
|
2007-07-07 09:27:28 +02:00
|
|
|
}
|
2011-11-06 18:18:20 +01:00
|
|
|
active_feature = features.end();
|
2010-06-30 08:29:14 +02:00
|
|
|
|
|
|
|
Save();
|
|
|
|
MakeFeatures();
|
2010-10-26 06:12:10 +02:00
|
|
|
Commit(_("delete control point"));
|
2010-06-30 08:29:14 +02:00
|
|
|
|
|
|
|
return false;
|
2007-07-07 07:51:18 +02:00
|
|
|
}
|
|
|
|
|
2010-05-20 10:55:35 +02:00
|
|
|
bool VisualToolVectorClip::InitializeHold() {
|
2007-07-07 08:41:14 +02:00
|
|
|
// Insert line/bicubic
|
|
|
|
if (mode == 1 || mode == 2) {
|
|
|
|
SplineCurve curve;
|
|
|
|
|
2011-11-06 18:18:20 +01:00
|
|
|
// New spline beginning at the clicked point
|
|
|
|
if (spline.empty()) {
|
|
|
|
curve.p1 = mouse_pos;
|
|
|
|
curve.type = SplineCurve::POINT;
|
2007-07-07 08:41:14 +02:00
|
|
|
}
|
|
|
|
else {
|
2011-11-06 18:18:20 +01:00
|
|
|
// Continue from the spline in progress
|
|
|
|
// Don't bother setting p2 as UpdateHold will handle that
|
|
|
|
curve.p1 = spline.back().EndPoint();
|
|
|
|
curve.type = mode == 1 ? SplineCurve::LINE : SplineCurve::BICUBIC;
|
2007-07-07 08:41:14 +02:00
|
|
|
}
|
|
|
|
|
2010-06-08 08:09:19 +02:00
|
|
|
spline.push_back(curve);
|
2011-11-06 18:18:20 +01:00
|
|
|
sel_features.clear();
|
2010-06-18 09:14:23 +02:00
|
|
|
MakeFeature(--spline.end());
|
2010-05-20 10:55:35 +02:00
|
|
|
UpdateHold();
|
|
|
|
return true;
|
2007-07-07 08:41:14 +02:00
|
|
|
}
|
|
|
|
|
2007-07-07 23:13:20 +02:00
|
|
|
// Convert and insert
|
2010-05-20 10:55:35 +02:00
|
|
|
if (mode == 3 || mode == 4) {
|
2007-07-07 23:13:20 +02:00
|
|
|
// Get closest point
|
|
|
|
Vector2D pt;
|
2010-06-08 08:09:19 +02:00
|
|
|
Spline::iterator curve;
|
2007-07-07 23:13:20 +02:00
|
|
|
float t;
|
2011-11-06 18:18:20 +01:00
|
|
|
spline.GetClosestParametricPoint(mouse_pos, curve, t, pt);
|
2007-07-07 23:13:20 +02:00
|
|
|
|
2011-11-06 18:18:20 +01:00
|
|
|
// Convert line <-> bicubic
|
2007-07-07 23:13:20 +02:00
|
|
|
if (mode == 3) {
|
2010-06-08 08:09:19 +02:00
|
|
|
if (curve != spline.end()) {
|
2011-11-06 18:18:20 +01:00
|
|
|
if (curve->type == SplineCurve::LINE) {
|
|
|
|
curve->type = SplineCurve::BICUBIC;
|
2010-06-08 08:09:19 +02:00
|
|
|
curve->p4 = curve->p2;
|
|
|
|
curve->p2 = curve->p1 * 0.75 + curve->p4 * 0.25;
|
|
|
|
curve->p3 = curve->p1 * 0.25 + curve->p4 * 0.75;
|
2007-07-08 09:22:09 +02:00
|
|
|
}
|
|
|
|
|
2011-11-06 18:18:20 +01:00
|
|
|
else if (curve->type == SplineCurve::BICUBIC) {
|
|
|
|
curve->type = SplineCurve::LINE;
|
2010-06-08 08:09:19 +02:00
|
|
|
curve->p2 = curve->p4;
|
2007-07-08 09:22:09 +02:00
|
|
|
}
|
|
|
|
}
|
2007-07-07 23:13:20 +02:00
|
|
|
}
|
|
|
|
// Insert
|
|
|
|
else {
|
2010-06-08 08:09:19 +02:00
|
|
|
if (spline.empty()) return false;
|
2007-08-03 19:22:06 +02:00
|
|
|
|
2007-07-07 23:13:20 +02:00
|
|
|
// Split the curve
|
2010-06-08 08:09:19 +02:00
|
|
|
if (curve == spline.end()) {
|
2011-11-06 18:18:20 +01:00
|
|
|
SplineCurve ct(spline.back().EndPoint(), spline.front().p1);
|
|
|
|
ct.p2 = ct.p1 * (1 - t) + ct.p2 * t;
|
2010-06-08 08:09:19 +02:00
|
|
|
spline.push_back(ct);
|
2007-07-07 23:13:20 +02:00
|
|
|
}
|
|
|
|
else {
|
2010-06-08 08:09:19 +02:00
|
|
|
SplineCurve c2;
|
2011-11-06 18:18:20 +01:00
|
|
|
curve->Split(*curve, c2, t);
|
2010-06-08 08:09:19 +02:00
|
|
|
spline.insert(++curve, c2);
|
2007-07-07 23:13:20 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-06-30 08:29:14 +02:00
|
|
|
Save();
|
|
|
|
MakeFeatures();
|
2010-10-26 06:12:10 +02:00
|
|
|
Commit();
|
2010-05-20 10:55:35 +02:00
|
|
|
return false;
|
2007-07-07 23:13:20 +02:00
|
|
|
}
|
|
|
|
|
2011-11-06 18:18:20 +01:00
|
|
|
// Freehand spline draw
|
2010-05-20 10:55:35 +02:00
|
|
|
if (mode == 6 || mode == 7) {
|
2011-11-06 18:18:20 +01:00
|
|
|
sel_features.clear();
|
2007-07-08 09:22:09 +02:00
|
|
|
features.clear();
|
2011-11-06 18:18:20 +01:00
|
|
|
active_feature = features.end();
|
2010-06-08 08:09:19 +02:00
|
|
|
spline.clear();
|
2011-11-06 18:18:20 +01:00
|
|
|
spline.push_back(SplineCurve(mouse_pos));
|
2010-05-20 10:55:35 +02:00
|
|
|
return true;
|
2007-07-07 08:41:14 +02:00
|
|
|
}
|
2011-11-06 18:18:20 +01:00
|
|
|
|
|
|
|
/// @todo box selection?
|
|
|
|
if (mode == 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Nothing to do for mode 5 (remove)
|
2010-05-20 10:55:35 +02:00
|
|
|
return false;
|
2007-07-07 07:51:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void VisualToolVectorClip::UpdateHold() {
|
2007-07-07 08:41:14 +02:00
|
|
|
if (mode == 1) {
|
2011-11-06 18:18:20 +01:00
|
|
|
spline.back().EndPoint() = mouse_pos;
|
|
|
|
features.back().pos = mouse_pos;
|
2007-07-07 08:41:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Insert bicubic
|
2010-06-18 09:14:23 +02:00
|
|
|
else if (mode == 2) {
|
2010-06-08 08:09:19 +02:00
|
|
|
SplineCurve &curve = spline.back();
|
2011-11-06 18:18:20 +01:00
|
|
|
curve.EndPoint() = mouse_pos;
|
2007-07-07 08:41:14 +02:00
|
|
|
|
|
|
|
// Control points
|
2010-06-08 08:09:19 +02:00
|
|
|
if (spline.size() > 1) {
|
2011-11-06 18:18:20 +01:00
|
|
|
SplineCurve &c0 = spline.back();
|
|
|
|
float len = (curve.p4 - curve.p1).Len();
|
|
|
|
curve.p2 = (c0.type == SplineCurve::LINE ? c0.p2 - c0.p1 : c0.p4 - c0.p3).Unit() * (0.25f * len) + curve.p1;
|
2007-07-07 08:41:14 +02:00
|
|
|
}
|
2011-11-06 18:18:20 +01:00
|
|
|
else
|
|
|
|
curve.p2 = curve.p1 * 0.75 + curve.p4 * 0.25;
|
2007-07-07 08:41:14 +02:00
|
|
|
curve.p3 = curve.p1 * 0.25 + curve.p4 * 0.75;
|
2010-06-30 08:29:14 +02:00
|
|
|
MakeFeatures();
|
2007-07-07 08:41:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Freehand
|
2010-06-18 09:14:23 +02:00
|
|
|
else if (mode == 6 || mode == 7) {
|
2010-06-08 08:09:19 +02:00
|
|
|
// See if distance is enough
|
|
|
|
Vector2D const& last = spline.back().EndPoint();
|
2011-11-06 18:18:20 +01:00
|
|
|
float len = (last - mouse_pos).SquareLen();
|
|
|
|
if (mode == 6 && len < 900) return;
|
|
|
|
if (mode == 7 && len < 3600) return;
|
2010-06-08 08:09:19 +02:00
|
|
|
|
2011-11-06 18:18:20 +01:00
|
|
|
spline.push_back(SplineCurve(last, mouse_pos));
|
2010-06-18 09:14:23 +02:00
|
|
|
MakeFeature(--spline.end());
|
2007-07-07 07:51:18 +02:00
|
|
|
}
|
|
|
|
|
2010-06-30 08:29:14 +02:00
|
|
|
if (mode == 3 || mode == 4) return;
|
|
|
|
|
2007-07-07 07:51:18 +02:00
|
|
|
// Smooth spline
|
2011-11-06 18:18:20 +01:00
|
|
|
if (!holding && mode == 7)
|
2010-06-18 09:14:23 +02:00
|
|
|
spline.Smooth();
|
2007-07-07 07:51:18 +02:00
|
|
|
|
2010-06-30 08:29:14 +02:00
|
|
|
Save();
|
2007-07-08 09:22:09 +02:00
|
|
|
|
|
|
|
// End freedraw
|
2010-06-18 09:14:23 +02:00
|
|
|
if (!holding && (mode == 6 || mode == 7)) {
|
|
|
|
SetMode(0);
|
2010-06-30 08:29:14 +02:00
|
|
|
MakeFeatures();
|
2010-06-18 09:14:23 +02:00
|
|
|
}
|
2007-07-07 07:51:18 +02:00
|
|
|
}
|
|
|
|
|
2007-07-05 06:32:46 +02:00
|
|
|
void VisualToolVectorClip::DoRefresh() {
|
2011-11-06 18:18:20 +01:00
|
|
|
if (!active_line) return;
|
2010-06-28 09:13:15 +02:00
|
|
|
|
|
|
|
wxString vect;
|
|
|
|
int scale;
|
2011-11-06 18:18:20 +01:00
|
|
|
vect = GetLineVectorClip(active_line, scale, inverse);
|
2010-06-28 09:13:15 +02:00
|
|
|
spline.DecodeFromASS(vect);
|
2010-06-30 08:29:14 +02:00
|
|
|
|
|
|
|
MakeFeatures();
|
2010-06-28 09:13:15 +02:00
|
|
|
SelectAll();
|
2007-07-05 06:32:46 +02:00
|
|
|
}
|
2010-06-18 09:14:23 +02:00
|
|
|
|
|
|
|
void VisualToolVectorClip::SelectAll() {
|
2011-11-06 18:18:20 +01:00
|
|
|
sel_features.clear();
|
|
|
|
for (feature_iterator it = features.begin(); it != features.end(); ++it)
|
|
|
|
sel_features.insert(it);
|
2010-06-18 09:14:23 +02:00
|
|
|
}
|