2011-11-06 18:18:20 +01:00
|
|
|
// Copyright (c) 2011, Thomas Goyne <plorkyeran@aegisub.org>
|
2007-07-01 05:36:17 +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-01 05:36:17 +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-01 05:36:17 +02:00
|
|
|
//
|
2009-07-29 07:43:02 +02:00
|
|
|
// Aegisub Project http://www.aegisub.org/
|
|
|
|
|
|
|
|
/// @file visual_tool_drag.cpp
|
|
|
|
/// @brief Position all visible subtitles by dragging visual typesetting tool
|
|
|
|
/// @ingroup visual_ts
|
2007-07-01 05:36:17 +02:00
|
|
|
|
2011-11-06 18:18:20 +01:00
|
|
|
#include "visual_tool_drag.h"
|
|
|
|
|
2007-07-01 05:36:17 +02:00
|
|
|
#include "ass_dialogue.h"
|
2009-09-10 15:06:40 +02:00
|
|
|
#include "ass_file.h"
|
2018-04-15 23:59:32 +02:00
|
|
|
#include "compat.h"
|
2011-01-16 08:17:36 +01:00
|
|
|
#include "include/aegisub/context.h"
|
2009-09-10 15:06:40 +02:00
|
|
|
#include "libresrc/libresrc.h"
|
2013-01-07 02:50:09 +01:00
|
|
|
#include "options.h"
|
2014-03-25 01:15:14 +01:00
|
|
|
#include "selection_controller.h"
|
2014-05-22 01:23:28 +02:00
|
|
|
#include "video_controller.h"
|
2012-03-09 01:23:04 +01:00
|
|
|
#include "video_display.h"
|
2007-07-01 05:36:17 +02:00
|
|
|
|
2014-05-29 00:19:05 +02:00
|
|
|
#include <libaegisub/format.h>
|
2014-04-23 22:53:24 +02:00
|
|
|
#include <libaegisub/make_unique.h>
|
2012-11-05 17:20:58 +01:00
|
|
|
|
2013-01-04 16:01:50 +01:00
|
|
|
#include <algorithm>
|
2014-03-05 17:28:14 +01:00
|
|
|
#include <boost/range/algorithm/binary_search.hpp>
|
2013-01-04 16:01:50 +01:00
|
|
|
|
|
|
|
#include <wx/toolbar.h>
|
|
|
|
|
2010-05-23 10:53:27 +02:00
|
|
|
static const DraggableFeatureType DRAG_ORIGIN = DRAG_BIG_TRIANGLE;
|
|
|
|
static const DraggableFeatureType DRAG_START = DRAG_BIG_SQUARE;
|
|
|
|
static const DraggableFeatureType DRAG_END = DRAG_BIG_CIRCLE;
|
2007-07-04 06:24:47 +02:00
|
|
|
|
2012-01-21 00:42:33 +01:00
|
|
|
#define ICON(name) (OPT_GET("App/Toolbar Icon Size")->GetInt() == 16 ? GETIMAGE(name ## _16) : GETIMAGE(name ## _24))
|
|
|
|
|
2011-11-06 18:18:20 +01:00
|
|
|
VisualToolDrag::VisualToolDrag(VideoDisplay *parent, agi::Context *context)
|
|
|
|
: VisualTool<VisualToolDragDraggableFeature>(parent, context)
|
2007-07-01 05:36:17 +02:00
|
|
|
{
|
2012-10-05 05:22:54 +02:00
|
|
|
connections.push_back(c->selectionController->AddSelectionListener(&VisualToolDrag::OnSelectedSetChanged, this));
|
2014-03-05 17:28:14 +01:00
|
|
|
auto const& sel_set = c->selectionController->GetSelectedSet();
|
|
|
|
selection.insert(begin(selection), begin(sel_set), end(sel_set));
|
2011-11-06 18:18:20 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
void VisualToolDrag::SetToolbar(wxToolBar *tb) {
|
|
|
|
toolbar = tb;
|
2012-01-21 00:42:33 +01:00
|
|
|
toolbar->AddTool(-1, _("Toggle between \\move and \\pos"), ICON(visual_move_conv_move));
|
2011-11-06 18:18:20 +01:00
|
|
|
toolbar->Realize();
|
|
|
|
toolbar->Show(true);
|
|
|
|
|
2013-12-12 03:25:13 +01:00
|
|
|
toolbar->Bind(wxEVT_TOOL, &VisualToolDrag::OnSubTool, this);
|
2007-07-04 06:24:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void VisualToolDrag::UpdateToggleButtons() {
|
2011-11-06 18:18:20 +01:00
|
|
|
bool to_move = true;
|
|
|
|
if (active_line) {
|
|
|
|
Vector2D p1, p2;
|
|
|
|
int t1, t2;
|
|
|
|
to_move = !GetLineMove(active_line, p1, p2, t1, t2);
|
2007-07-04 06:24:47 +02:00
|
|
|
}
|
|
|
|
|
2011-11-06 18:18:20 +01:00
|
|
|
if (to_move == button_is_move) return;
|
2007-07-04 06:24:47 +02:00
|
|
|
|
2011-11-06 18:18:20 +01:00
|
|
|
toolbar->SetToolNormalBitmap(toolbar->GetToolByPos(0)->GetId(),
|
2012-01-21 00:42:33 +01:00
|
|
|
to_move ? ICON(visual_move_conv_move) : ICON(visual_move_conv_pos));
|
2011-11-06 18:18:20 +01:00
|
|
|
button_is_move = to_move;
|
2007-07-04 06:24:47 +02:00
|
|
|
}
|
|
|
|
|
2010-05-26 09:17:46 +02:00
|
|
|
void VisualToolDrag::OnSubTool(wxCommandEvent &) {
|
2007-07-04 06:24:47 +02:00
|
|
|
// Toggle \move <-> \pos
|
2014-05-22 01:23:28 +02:00
|
|
|
VideoController *vc = c->videoController.get();
|
2012-11-04 04:53:03 +01:00
|
|
|
for (auto line : selection) {
|
2011-11-06 18:18:20 +01:00
|
|
|
Vector2D p1, p2;
|
|
|
|
int t1, t2;
|
2010-05-26 09:17:46 +02:00
|
|
|
|
2011-11-06 18:18:20 +01:00
|
|
|
bool has_move = GetLineMove(line, p1, p2, t1, t2);
|
2007-07-04 06:24:47 +02:00
|
|
|
|
2011-11-06 18:18:20 +01:00
|
|
|
if (has_move)
|
|
|
|
SetOverride(line, "\\pos", p1.PStr());
|
|
|
|
else {
|
|
|
|
p1 = GetLinePosition(line);
|
|
|
|
// Round the start and end times to exact frames
|
2011-12-22 22:28:51 +01:00
|
|
|
int start = vc->TimeAtFrame(vc->FrameAtTime(line->Start, agi::vfr::START)) - line->Start;
|
|
|
|
int end = vc->TimeAtFrame(vc->FrameAtTime(line->Start, agi::vfr::END)) - line->Start;
|
2014-05-29 00:19:05 +02:00
|
|
|
SetOverride(line, "\\move", agi::format("(%s,%s,%d,%d)", p1.Str(), p1.Str(), start, end));
|
2011-11-06 18:18:20 +01:00
|
|
|
}
|
2007-07-04 06:24:47 +02:00
|
|
|
}
|
2010-05-26 09:17:46 +02:00
|
|
|
|
2010-10-26 06:12:10 +02:00
|
|
|
Commit();
|
2011-11-06 18:18:20 +01:00
|
|
|
OnFileChanged();
|
2010-10-16 22:23:54 +02:00
|
|
|
UpdateToggleButtons();
|
2007-07-04 06:24:47 +02:00
|
|
|
}
|
|
|
|
|
2010-06-28 09:13:15 +02:00
|
|
|
void VisualToolDrag::OnLineChanged() {
|
2007-07-04 06:24:47 +02:00
|
|
|
UpdateToggleButtons();
|
2007-07-01 05:36:17 +02:00
|
|
|
}
|
|
|
|
|
2010-06-28 09:13:15 +02:00
|
|
|
void VisualToolDrag::OnFileChanged() {
|
2010-06-30 08:29:14 +02:00
|
|
|
/// @todo it should be possible to preserve the selection in some cases
|
|
|
|
features.clear();
|
2011-11-06 18:18:20 +01:00
|
|
|
sel_features.clear();
|
2013-11-21 18:13:36 +01:00
|
|
|
primary = nullptr;
|
2013-09-17 20:13:52 +02:00
|
|
|
active_feature = nullptr;
|
2011-11-06 18:18:20 +01:00
|
|
|
|
2014-03-07 19:58:51 +01:00
|
|
|
for (auto& diag : c->ass->Events) {
|
|
|
|
if (IsDisplayed(&diag))
|
|
|
|
MakeFeatures(&diag);
|
2010-06-30 08:29:14 +02:00
|
|
|
}
|
2011-11-06 18:18:20 +01:00
|
|
|
|
2010-10-16 22:23:54 +02:00
|
|
|
UpdateToggleButtons();
|
2010-06-28 09:13:15 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void VisualToolDrag::OnFrameChanged() {
|
2011-11-06 18:18:20 +01:00
|
|
|
if (primary && !IsDisplayed(primary->line))
|
2013-11-21 18:13:36 +01:00
|
|
|
primary = nullptr;
|
2010-06-30 08:29:14 +02:00
|
|
|
|
2013-09-17 20:13:52 +02:00
|
|
|
auto feat = features.begin();
|
|
|
|
auto end = features.end();
|
2010-06-30 08:29:14 +02:00
|
|
|
|
2014-03-07 19:58:51 +01:00
|
|
|
for (auto& diag : c->ass->Events) {
|
|
|
|
if (IsDisplayed(&diag)) {
|
2010-06-30 08:29:14 +02:00
|
|
|
// Features don't exist and should
|
2014-03-07 19:58:51 +01:00
|
|
|
if (feat == end || feat->line != &diag)
|
|
|
|
MakeFeatures(&diag, feat);
|
2010-06-30 08:29:14 +02:00
|
|
|
// Move past already existing features for the line
|
2011-11-06 18:18:20 +01:00
|
|
|
else
|
2014-03-07 19:58:51 +01:00
|
|
|
while (feat != end && feat->line == &diag) ++feat;
|
2010-06-30 08:29:14 +02:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
// Remove all features for this line (if any)
|
2014-03-07 19:58:51 +01:00
|
|
|
while (feat != end && feat->line == &diag) {
|
2013-09-17 20:13:52 +02:00
|
|
|
if (&*feat == active_feature) active_feature = nullptr;
|
|
|
|
feat->line = nullptr;
|
|
|
|
RemoveSelection(&*feat);
|
2010-06-30 08:29:14 +02:00
|
|
|
feat = features.erase(feat);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-06-28 09:13:15 +02:00
|
|
|
}
|
|
|
|
|
2012-03-15 01:25:54 +01:00
|
|
|
template<class C, class T> static bool line_not_present(C const& set, T const& it) {
|
2013-09-17 20:13:52 +02:00
|
|
|
return std::none_of(set.begin(), set.end(), [&](typename C::value_type const& cmp) {
|
|
|
|
return cmp->line == it->line;
|
|
|
|
});
|
2012-03-15 01:25:54 +01:00
|
|
|
}
|
|
|
|
|
2014-03-05 17:28:14 +01:00
|
|
|
void VisualToolDrag::OnSelectedSetChanged() {
|
|
|
|
auto const& new_sel_set = c->selectionController->GetSelectedSet();
|
|
|
|
std::vector<AssDialogue *> new_sel(begin(new_sel_set), end(new_sel_set));
|
Remove the SelectionChangeSubscriber mechanism from the grid and implement some basic selection change notification through SelectionController.
Change SelectionListener interface so it receives the set of lines added and removed from selection, instead of just the complete new selection.
Update VisualTool<> to use SelectionListener to receive selection change notifications.
This change (temporarily, I hope) breaks feature selection in visual drag mode, when changing selection via the grid. This is caused by the grid selection change first clearing the entire selection, which sends a separate notification about selection clear. This causes the last visual feature to be deselected, and then the visual tool base reselects the active line, causing a new notification for selection to be sent. The active line happens to be the newly clicked line, and the selection notification enters during the externalChange guard being set, and is then ignored for feature update purposes. When control returns to the original SelectRow call in the grid, the line to be selected has already been selected and then nothing happens.
The best fix is to avoid two notifications being required to deselect all then reselect one line in the first place, so making the grid selection handling saner is the best fix.
Originally committed to SVN as r4602.
2010-06-26 06:38:02 +02:00
|
|
|
|
2012-03-09 01:23:04 +01:00
|
|
|
bool any_changed = false;
|
2013-09-17 20:13:52 +02:00
|
|
|
for (auto it = features.begin(); it != features.end(); ) {
|
2014-03-05 17:28:14 +01:00
|
|
|
bool was_selected = boost::binary_search(selection, it->line);
|
|
|
|
bool is_selected = boost::binary_search(new_sel, it->line);
|
|
|
|
if (was_selected && !is_selected) {
|
2013-09-17 20:13:52 +02:00
|
|
|
sel_features.erase(&*it++);
|
2012-03-09 01:23:04 +01:00
|
|
|
any_changed = true;
|
|
|
|
}
|
2012-10-15 06:37:14 +02:00
|
|
|
else {
|
2014-03-05 17:28:14 +01:00
|
|
|
if (is_selected && !was_selected && it->type == DRAG_START && line_not_present(sel_features, it)) {
|
2013-09-17 20:13:52 +02:00
|
|
|
sel_features.insert(&*it);
|
2012-10-15 06:37:14 +02:00
|
|
|
any_changed = true;
|
|
|
|
}
|
|
|
|
++it;
|
2012-03-09 01:23:04 +01:00
|
|
|
}
|
2010-05-26 09:17:39 +02:00
|
|
|
}
|
2012-03-09 01:23:04 +01:00
|
|
|
|
|
|
|
if (any_changed)
|
|
|
|
parent->Render();
|
2014-03-05 17:28:14 +01:00
|
|
|
selection = std::move(new_sel);
|
2010-05-26 09:17:39 +02:00
|
|
|
}
|
|
|
|
|
2007-07-01 05:36:17 +02:00
|
|
|
void VisualToolDrag::Draw() {
|
2007-07-01 09:09:37 +02:00
|
|
|
DrawAllFeatures();
|
2007-07-04 02:36:04 +02:00
|
|
|
|
2018-04-15 23:59:32 +02:00
|
|
|
// Load colors from options
|
|
|
|
wxColour line_color = to_wx(line_color_primary_opt->GetColor());
|
|
|
|
|
2011-11-06 18:18:20 +01:00
|
|
|
// Draw connecting lines
|
2013-09-17 20:13:52 +02:00
|
|
|
for (auto& feature : features) {
|
|
|
|
if (feature.type == DRAG_START) continue;
|
2011-11-06 18:18:20 +01:00
|
|
|
|
2013-09-17 20:13:52 +02:00
|
|
|
Feature *p2 = &feature;
|
|
|
|
Feature *p1 = feature.parent;
|
2010-05-20 10:55:52 +02:00
|
|
|
|
2011-11-06 18:18:20 +01:00
|
|
|
// Move end marker has an arrow; origin doesn't
|
|
|
|
bool has_arrow = p2->type == DRAG_END;
|
|
|
|
int arrow_len = has_arrow ? 10 : 0;
|
|
|
|
|
|
|
|
// Don't show the connecting line if the features are very close
|
|
|
|
Vector2D direction = p2->pos - p1->pos;
|
|
|
|
if (direction.SquareLen() < (20 + arrow_len) * (20 + arrow_len)) continue;
|
|
|
|
|
|
|
|
direction = direction.Unit();
|
|
|
|
// Get the start and end points of the line
|
|
|
|
Vector2D start = p1->pos + direction * 10;
|
|
|
|
Vector2D end = p2->pos - direction * (10 + arrow_len);
|
|
|
|
|
|
|
|
if (has_arrow) {
|
2018-04-15 23:59:32 +02:00
|
|
|
gl.SetLineColour(line_color, 0.8f, 2);
|
2010-05-20 10:55:52 +02:00
|
|
|
|
|
|
|
// Arrow line
|
2011-11-06 18:18:20 +01:00
|
|
|
gl.DrawLine(start, end);
|
2010-05-20 10:55:52 +02:00
|
|
|
|
|
|
|
// Arrow head
|
2011-11-06 18:18:20 +01:00
|
|
|
Vector2D t_half_base_w = Vector2D(-direction.Y(), direction.X()) * 4;
|
|
|
|
gl.DrawTriangle(end + direction * arrow_len, end + t_half_base_w, end - t_half_base_w);
|
2010-05-20 10:55:52 +02:00
|
|
|
}
|
|
|
|
// Draw dashed line
|
|
|
|
else {
|
2018-04-15 23:59:32 +02:00
|
|
|
gl.SetLineColour(line_color, 0.5f, 2);
|
2011-11-06 18:18:20 +01:00
|
|
|
gl.DrawDashedLine(start, end, 6);
|
2007-07-04 02:36:04 +02:00
|
|
|
}
|
|
|
|
}
|
2007-07-01 05:36:17 +02:00
|
|
|
}
|
2011-11-06 18:18:20 +01:00
|
|
|
|
2010-06-30 08:29:14 +02:00
|
|
|
void VisualToolDrag::MakeFeatures(AssDialogue *diag) {
|
|
|
|
MakeFeatures(diag, features.end());
|
2010-05-26 09:17:39 +02:00
|
|
|
}
|
2011-11-06 18:18:20 +01:00
|
|
|
|
2013-09-17 20:13:52 +02:00
|
|
|
void VisualToolDrag::MakeFeatures(AssDialogue *diag, feature_list::iterator pos) {
|
2011-11-06 18:18:20 +01:00
|
|
|
Vector2D p1 = FromScriptCoords(GetLinePosition(diag));
|
2010-06-30 08:29:14 +02:00
|
|
|
|
|
|
|
// Create \pos feature
|
2014-04-23 22:53:24 +02:00
|
|
|
auto feat = agi::make_unique<Feature>();
|
2013-09-17 20:13:52 +02:00
|
|
|
auto parent = feat.get();
|
|
|
|
feat->pos = p1;
|
|
|
|
feat->type = DRAG_START;
|
|
|
|
feat->line = diag;
|
|
|
|
|
2014-03-05 17:28:14 +01:00
|
|
|
if (boost::binary_search(selection, diag))
|
2013-09-17 20:13:52 +02:00
|
|
|
sel_features.insert(feat.get());
|
|
|
|
features.insert(pos, *feat.release());
|
2011-11-06 18:18:20 +01:00
|
|
|
|
|
|
|
Vector2D p2;
|
|
|
|
int t1, t2;
|
2007-07-01 09:09:37 +02:00
|
|
|
|
2010-06-30 08:29:14 +02:00
|
|
|
// Create move destination feature
|
2011-11-06 18:18:20 +01:00
|
|
|
if (GetLineMove(diag, p1, p2, t1, t2)) {
|
2014-04-23 22:53:24 +02:00
|
|
|
feat = agi::make_unique<Feature>();
|
2013-09-17 20:13:52 +02:00
|
|
|
feat->pos = FromScriptCoords(p2);
|
|
|
|
feat->layer = 1;
|
|
|
|
feat->type = DRAG_END;
|
|
|
|
feat->time = t2;
|
|
|
|
feat->line = diag;
|
|
|
|
feat->parent = parent;
|
|
|
|
|
|
|
|
parent->time = t1;
|
|
|
|
parent->parent = feat.get();
|
|
|
|
|
|
|
|
features.insert(pos, *feat.release());
|
2010-06-30 08:29:14 +02:00
|
|
|
}
|
2011-11-06 18:18:20 +01:00
|
|
|
|
2010-06-30 08:29:14 +02:00
|
|
|
// Create org feature
|
2011-11-06 18:18:20 +01:00
|
|
|
if (Vector2D org = GetLineOrigin(diag)) {
|
2014-04-23 22:53:24 +02:00
|
|
|
feat = agi::make_unique<Feature>();
|
2013-09-17 20:13:52 +02:00
|
|
|
feat->pos = FromScriptCoords(org);
|
|
|
|
feat->layer = -1;
|
|
|
|
feat->type = DRAG_ORIGIN;
|
|
|
|
feat->time = 0;
|
|
|
|
feat->line = diag;
|
|
|
|
feat->parent = parent;
|
|
|
|
features.insert(pos, *feat.release());
|
2010-06-30 08:29:14 +02:00
|
|
|
}
|
|
|
|
}
|
2007-07-01 09:09:37 +02:00
|
|
|
|
2013-09-17 20:13:52 +02:00
|
|
|
bool VisualToolDrag::InitializeDrag(Feature *feature) {
|
|
|
|
primary = feature;
|
2010-05-26 09:17:39 +02:00
|
|
|
|
2010-06-30 08:29:14 +02:00
|
|
|
// Set time of clicked feature to the current frame and shift all other
|
|
|
|
// selected features by the same amount
|
|
|
|
if (feature->type != DRAG_ORIGIN) {
|
2011-12-22 22:28:51 +01:00
|
|
|
int time = c->videoController->TimeAtFrame(frame_number) - feature->line->Start;
|
2010-06-30 08:29:14 +02:00
|
|
|
int change = time - feature->time;
|
2010-05-26 09:17:39 +02:00
|
|
|
|
2012-11-04 04:53:03 +01:00
|
|
|
for (auto feat : sel_features)
|
|
|
|
feat->time += change;
|
2007-07-01 09:09:37 +02:00
|
|
|
}
|
2010-05-23 10:53:27 +02:00
|
|
|
return true;
|
|
|
|
}
|
2007-07-01 09:09:37 +02:00
|
|
|
|
2013-09-17 20:13:52 +02:00
|
|
|
void VisualToolDrag::UpdateDrag(Feature *feature) {
|
2010-05-23 10:53:27 +02:00
|
|
|
if (feature->type == DRAG_ORIGIN) {
|
2011-11-06 18:18:20 +01:00
|
|
|
SetOverride(feature->line, "\\org", ToScriptCoords(feature->pos).PStr());
|
2010-05-20 10:55:52 +02:00
|
|
|
return;
|
2007-07-04 09:26:24 +02:00
|
|
|
}
|
|
|
|
|
2013-09-17 20:13:52 +02:00
|
|
|
Feature *end_feature = feature->parent;
|
2011-11-06 18:18:20 +01:00
|
|
|
if (feature->type == DRAG_END)
|
|
|
|
std::swap(feature, end_feature);
|
|
|
|
|
2013-09-17 20:13:52 +02:00
|
|
|
if (!feature->parent)
|
2011-11-06 18:18:20 +01:00
|
|
|
SetOverride(feature->line, "\\pos", ToScriptCoords(feature->pos).PStr());
|
|
|
|
else
|
2014-05-29 00:19:05 +02:00
|
|
|
SetOverride(feature->line, "\\move", agi::format("(%s,%s,%d,%d)"
|
|
|
|
, ToScriptCoords(feature->pos).Str()
|
|
|
|
, ToScriptCoords(end_feature->pos).Str()
|
|
|
|
, feature->time , end_feature->time));
|
2007-07-01 05:36:17 +02:00
|
|
|
}
|
2010-05-23 10:53:27 +02:00
|
|
|
|
2011-11-06 18:18:20 +01:00
|
|
|
void VisualToolDrag::OnDoubleClick() {
|
|
|
|
Vector2D d = ToScriptCoords(mouse_pos) - (primary ? ToScriptCoords(primary->pos) : GetLinePosition(active_line));
|
|
|
|
|
2012-11-04 04:53:03 +01:00
|
|
|
for (auto line : c->selectionController->GetSelectedSet()) {
|
2011-11-06 18:18:20 +01:00
|
|
|
Vector2D p1, p2;
|
|
|
|
int t1, t2;
|
2012-11-04 04:53:03 +01:00
|
|
|
if (GetLineMove(line, p1, p2, t1, t2)) {
|
2011-11-06 18:18:20 +01:00
|
|
|
if (t1 > 0 || t2 > 0)
|
2014-05-29 00:19:05 +02:00
|
|
|
SetOverride(line, "\\move", agi::format("(%s,%s,%d,%d)", (p1 + d).Str(), (p2 + d).Str(), t1, t2));
|
2010-05-23 10:53:27 +02:00
|
|
|
else
|
2014-05-29 00:19:05 +02:00
|
|
|
SetOverride(line, "\\move", agi::format("(%s,%s)", (p1 + d).Str(), (p2 + d).Str()));
|
2010-05-26 09:17:28 +02:00
|
|
|
}
|
2011-11-06 18:18:20 +01:00
|
|
|
else
|
2012-11-04 04:53:03 +01:00
|
|
|
SetOverride(line, "\\pos", (GetLinePosition(line) + d).PStr());
|
2011-11-06 18:18:20 +01:00
|
|
|
|
2012-11-04 04:53:03 +01:00
|
|
|
if (Vector2D org = GetLineOrigin(line))
|
|
|
|
SetOverride(line, "\\org", (org + d).PStr());
|
2010-05-23 10:53:27 +02:00
|
|
|
}
|
|
|
|
|
2010-10-26 06:12:10 +02:00
|
|
|
Commit(_("positioning"));
|
2010-05-23 10:53:27 +02:00
|
|
|
|
2010-06-30 08:29:14 +02:00
|
|
|
OnFileChanged();
|
2010-05-23 10:53:27 +02:00
|
|
|
}
|