forked from mia/Aegisub
Add selection and control of multiple visual features
Make all visual tools support selecting and manipulating multiple visual features at once, allowing multiple lines to be moved at once, entire vector clips to be translated, etc. Controls: - Left click: Select control clicked control only - Ctrl-left click: Add/remove control to selection - Drag control (with or without ctrl): Move all selected controls, after setting/adding to selection if target is not in the selection - Click on no control: Clear selection Lots of little stuff to fix still. Updates #513. Originally committed to SVN as r4322.
This commit is contained in:
parent
8ff2728322
commit
23972b10bc
17 changed files with 299 additions and 234 deletions
|
@ -97,24 +97,30 @@ VideoContext *VideoContext::instance = NULL;
|
|||
/// @brief Constructor
|
||||
///
|
||||
VideoContext::VideoContext()
|
||||
: glContext(NULL)
|
||||
, ownGlContext(false)
|
||||
, audio(NULL)
|
||||
: ownGlContext(false)
|
||||
, glContext(NULL)
|
||||
, provider(NULL)
|
||||
, subsProvider(NULL)
|
||||
, curLine(NULL)
|
||||
, loaded(false)
|
||||
, keyFramesLoaded(false)
|
||||
, overKeyFramesLoaded(false)
|
||||
, startFrame(-1)
|
||||
, endFrame(-1)
|
||||
, playNextFrame(-1)
|
||||
, nextFrame(-1)
|
||||
, loaded(false)
|
||||
, isPlaying(false)
|
||||
, keepAudioSync(true)
|
||||
, w(-1)
|
||||
, h(-1)
|
||||
, frame_n(0)
|
||||
, length(0)
|
||||
, fps(0)
|
||||
, arType(0)
|
||||
, arValue(1.)
|
||||
, isPlaying(false)
|
||||
, nextFrame(-1)
|
||||
, keepAudioSync(true)
|
||||
, arType(0)
|
||||
, hasSubtitles(false)
|
||||
, grid(NULL)
|
||||
, curLine(NULL)
|
||||
, audio(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
//
|
||||
// $Id$
|
||||
|
||||
/// @file visual_feature.cpp
|
||||
/// @file visual_feature->cpp
|
||||
/// @brief Feature on video the user can interact with using mouse
|
||||
/// @ingroup visual_ts
|
||||
///
|
||||
|
@ -43,13 +43,16 @@ VisualDraggableFeature::VisualDraggableFeature()
|
|||
: type(DRAG_NONE)
|
||||
, x(INT_MIN)
|
||||
, y(INT_MIN)
|
||||
, origX(INT_MIN)
|
||||
, origY(INT_MIN)
|
||||
, selected(false)
|
||||
, layer(0)
|
||||
, line(NULL)
|
||||
, lineN(-1)
|
||||
{
|
||||
}
|
||||
|
||||
bool VisualDraggableFeature::IsMouseOver(int mx,int my) {
|
||||
bool VisualDraggableFeature::IsMouseOver(int mx,int my) const {
|
||||
switch (type) {
|
||||
case DRAG_BIG_SQUARE:
|
||||
return !(mx < x-8 || mx > x+8 || my < y-8 || my > y+8);
|
||||
|
@ -77,7 +80,7 @@ bool VisualDraggableFeature::IsMouseOver(int mx,int my) {
|
|||
}
|
||||
}
|
||||
|
||||
void VisualDraggableFeature::Draw(OpenGLWrapper const& gl) {
|
||||
void VisualDraggableFeature::Draw(OpenGLWrapper const& gl) const {
|
||||
switch (type) {
|
||||
case DRAG_BIG_SQUARE:
|
||||
gl.DrawRectangle(x-8,y-8,x+8,y+8);
|
||||
|
|
|
@ -29,8 +29,8 @@
|
|||
//
|
||||
// $Id$
|
||||
|
||||
/// @file visual_feature.h
|
||||
/// @see visual_feature.cpp
|
||||
/// @file visual_feature->h
|
||||
/// @see visual_feature->cpp
|
||||
/// @ingroup visual_ts
|
||||
///
|
||||
|
||||
|
@ -75,6 +75,11 @@ public:
|
|||
int x; /// x coordinate
|
||||
int y; /// y coordinate
|
||||
|
||||
int origX; /// x coordindate before the last operation began
|
||||
int origY; /// y coordindate before the last operation began
|
||||
|
||||
bool selected; ///Iis this feature selected?
|
||||
|
||||
int layer; /// Layer; Higher = above
|
||||
|
||||
AssDialogue* line; /// The dialogue line this feature is for
|
||||
|
@ -83,8 +88,8 @@ public:
|
|||
/// @brief Is the given point over this feature?
|
||||
/// @param mx x coordinate to test
|
||||
/// @param my y coordinate to test
|
||||
bool IsMouseOver(int x,int y);
|
||||
bool IsMouseOver(int x,int y) const;
|
||||
/// @brief Draw this feature
|
||||
/// @param gl OpenGLWrapper to use
|
||||
void Draw(OpenGLWrapper const& gl);
|
||||
void Draw(OpenGLWrapper const& gl) const;
|
||||
};
|
||||
|
|
|
@ -67,18 +67,25 @@
|
|||
|
||||
const wxColour IVisualTool::colour[4] = {wxColour(106,32,19), wxColour(255,169,40), wxColour(255,253,185), wxColour(187,0,0)};
|
||||
|
||||
/// @brief Constructor
|
||||
/// @param parent
|
||||
template<class FeatureType>
|
||||
VisualTool<FeatureType>::VisualTool(VideoDisplay *parent, VideoState const& video)
|
||||
: parent(parent)
|
||||
: dragStartX(0)
|
||||
, dragStartY(0)
|
||||
, externalChange(true)
|
||||
, selChanged(false)
|
||||
, parent(parent)
|
||||
, holding(false)
|
||||
, curDiag(NULL)
|
||||
, dragging(false)
|
||||
, curFeature(-1)
|
||||
, curFeature(NULL)
|
||||
, dragListOK(false)
|
||||
, video(video)
|
||||
, frame_n(0)
|
||||
, video(video)
|
||||
, leftClick(false)
|
||||
, leftDClick(false)
|
||||
, shiftDown(false)
|
||||
, ctrlDown(false)
|
||||
, altDown(false)
|
||||
{
|
||||
if (VideoContext::Get()->IsLoaded()) {
|
||||
frame_n = VideoContext::Get()->GetFrameN();
|
||||
|
@ -87,13 +94,10 @@ VisualTool<FeatureType>::VisualTool(VideoDisplay *parent, VideoState const& vide
|
|||
PopulateFeatureList();
|
||||
}
|
||||
|
||||
/// @brief Destructor
|
||||
template<class FeatureType>
|
||||
VisualTool<FeatureType>::~VisualTool() {
|
||||
}
|
||||
|
||||
/// @brief Mouse event
|
||||
/// @param event
|
||||
template<class FeatureType>
|
||||
void VisualTool<FeatureType>::OnMouseEvent (wxMouseEvent &event) {
|
||||
bool realTime = Options.AsBool(L"Video Visual Realtime");
|
||||
|
@ -102,6 +106,9 @@ void VisualTool<FeatureType>::OnMouseEvent (wxMouseEvent &event) {
|
|||
Update();
|
||||
return;
|
||||
}
|
||||
externalChange = false;
|
||||
|
||||
VideoContext* con = VideoContext::Get();
|
||||
|
||||
leftClick = event.ButtonDown(wxMOUSE_BTN_LEFT);
|
||||
leftDClick = event.LeftDClick();
|
||||
|
@ -121,32 +128,62 @@ void VisualTool<FeatureType>::OnMouseEvent (wxMouseEvent &event) {
|
|||
if (dragging) {
|
||||
// continue drag
|
||||
if (event.LeftIsDown()) {
|
||||
features[curFeature].x = (video.x - dragStartX + dragOrigX);
|
||||
features[curFeature].y = (video.y - dragStartY + dragOrigY);
|
||||
for (SelFeatureIter cur = selFeatures.begin(); cur != selFeatures.end(); ++cur) {
|
||||
(*cur)->x = (video.x - dragStartX + (*cur)->origX);
|
||||
(*cur)->y = (video.y - dragStartY + (*cur)->origY);
|
||||
if (shiftDown) {
|
||||
if (abs(video.x - dragStartX) > abs(video.y - dragStartY)) {
|
||||
features[curFeature].y = dragOrigY;
|
||||
(*cur)->y = (*cur)->origY;
|
||||
}
|
||||
else {
|
||||
features[curFeature].x = dragOrigX;
|
||||
(*cur)->x = (*cur)->origX;
|
||||
}
|
||||
}
|
||||
UpdateDrag(features[curFeature]);
|
||||
UpdateDrag(*cur);
|
||||
|
||||
if (realTime) {
|
||||
CommitDrag(features[curFeature]);
|
||||
Commit();
|
||||
CommitDrag(*cur);
|
||||
}
|
||||
}
|
||||
if (realTime) Commit();
|
||||
}
|
||||
// end drag
|
||||
else {
|
||||
if (realTime) AssLimitToVisibleFilter::SetFrame(-1);
|
||||
|
||||
dragging = false;
|
||||
CommitDrag(features[curFeature]);
|
||||
Commit(true);
|
||||
|
||||
curFeature = -1;
|
||||
// mouse didn't move, fiddle with selection
|
||||
if (curFeature->x == curFeature->origX && curFeature->y == curFeature->origY) {
|
||||
// Don't deselect stuff that was selected in this click's mousedown event
|
||||
if (!selChanged) {
|
||||
if (ctrlDown) {
|
||||
// deselect this feature
|
||||
selFeatures.remove(curFeature);
|
||||
curFeature->selected = false;
|
||||
if (curFeature->lineN > -1) {
|
||||
con->grid->SelectRow(curFeature->lineN, true, false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// deselect everything else
|
||||
ClearSelection();
|
||||
selFeatures.push_back(curFeature);
|
||||
curFeature->selected = true;
|
||||
if (curFeature->lineN > -1) {
|
||||
con->grid->SelectRow(curFeature->lineN, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (SelFeatureIter cur = selFeatures.begin(); cur != selFeatures.end(); ++cur) {
|
||||
CommitDrag(*cur);
|
||||
}
|
||||
Commit(true);
|
||||
}
|
||||
|
||||
curFeature = NULL;
|
||||
parent->ReleaseMouse();
|
||||
parent->SetFocus();
|
||||
}
|
||||
|
@ -177,17 +214,33 @@ void VisualTool<FeatureType>::OnMouseEvent (wxMouseEvent &event) {
|
|||
else if (leftClick) {
|
||||
curFeature = GetHighlightedFeature();
|
||||
// start drag
|
||||
if (curFeature > -1) {
|
||||
if (InitializeDrag(features[curFeature])) {
|
||||
if (features[curFeature].lineN != -1) {
|
||||
VideoContext::Get()->grid->editBox->SetToLine(features[curFeature].lineN,true);
|
||||
VideoContext::Get()->grid->SelectRow(features[curFeature].lineN);
|
||||
if (curFeature) {
|
||||
if (InitializeDrag(curFeature)) {
|
||||
if (!curFeature->selected) {
|
||||
selChanged = true;
|
||||
if (!ctrlDown) {
|
||||
ClearSelection();
|
||||
}
|
||||
selFeatures.push_back(curFeature);
|
||||
curFeature->selected = true;
|
||||
if (curFeature->lineN != -1) {
|
||||
con->grid->editBox->SetToLine(curFeature->lineN,true);
|
||||
con->grid->SelectRow(curFeature->lineN, ctrlDown);
|
||||
}
|
||||
}
|
||||
else {
|
||||
selChanged = false;
|
||||
if (curFeature->lineN != -1) {
|
||||
con->grid->editBox->SetToLine(curFeature->lineN,true);
|
||||
}
|
||||
}
|
||||
|
||||
dragStartX = video.x;
|
||||
dragStartY = video.y;
|
||||
dragOrigX = features[curFeature].x;
|
||||
dragOrigY = features[curFeature].y;
|
||||
for (SelFeatureIter cur = selFeatures.begin(); cur != selFeatures.end(); ++cur) {
|
||||
(*cur)->origX = (*cur)->x;
|
||||
(*cur)->origY = (*cur)->y;
|
||||
}
|
||||
|
||||
dragging = true;
|
||||
parent->CaptureMouse();
|
||||
|
@ -196,6 +249,7 @@ void VisualTool<FeatureType>::OnMouseEvent (wxMouseEvent &event) {
|
|||
}
|
||||
// start hold
|
||||
else {
|
||||
ClearSelection();
|
||||
curDiag = GetActiveDialogueLine();
|
||||
if (curDiag && InitializeHold()) {
|
||||
holding = true;
|
||||
|
@ -206,10 +260,9 @@ void VisualTool<FeatureType>::OnMouseEvent (wxMouseEvent &event) {
|
|||
}
|
||||
|
||||
Update();
|
||||
externalChange = true;
|
||||
}
|
||||
|
||||
/// @brief Commit
|
||||
/// @param full
|
||||
template<class FeatureType>
|
||||
void VisualTool<FeatureType>::Commit(bool full) {
|
||||
SubtitlesGrid *grid = VideoContext::Get()->grid;
|
||||
|
@ -218,8 +271,6 @@ void VisualTool<FeatureType>::Commit(bool full) {
|
|||
grid->editBox->Update(false, true, false);
|
||||
}
|
||||
|
||||
/// @brief Get active dialogue line
|
||||
/// @return
|
||||
template<class FeatureType>
|
||||
AssDialogue* VisualTool<FeatureType>::GetActiveDialogueLine() {
|
||||
SubtitlesGrid *grid = VideoContext::Get()->grid;
|
||||
|
@ -236,22 +287,19 @@ AssDialogue* VisualTool<FeatureType>::GetActiveDialogueLine() {
|
|||
return diag;
|
||||
}
|
||||
|
||||
/// @brief Get feature under mouse
|
||||
/// @return
|
||||
template<class FeatureType>
|
||||
int VisualTool<FeatureType>::GetHighlightedFeature() {
|
||||
FeatureType* VisualTool<FeatureType>::GetHighlightedFeature() {
|
||||
int highestLayerFound = INT_MIN;
|
||||
int bestMatch = -1;
|
||||
for (size_t i=0;i<features.size();i++) {
|
||||
if (features[i].IsMouseOver(video.x, video.y) && features[i].layer > highestLayerFound) {
|
||||
bestMatch = i;
|
||||
highestLayerFound = features[i].layer;
|
||||
FeatureType* bestMatch = NULL;
|
||||
for (FeatureIter cur = features.begin(); cur != features.end(); ++cur) {
|
||||
if (cur->IsMouseOver(video.x, video.y) && cur->layer > highestLayerFound) {
|
||||
bestMatch = &*cur;
|
||||
highestLayerFound = cur->layer;
|
||||
}
|
||||
}
|
||||
return bestMatch;
|
||||
}
|
||||
|
||||
/// @brief Draw all features
|
||||
template<class FeatureType>
|
||||
void VisualTool<FeatureType>::DrawAllFeatures() {
|
||||
if (!dragListOK) {
|
||||
|
@ -259,31 +307,40 @@ void VisualTool<FeatureType>::DrawAllFeatures() {
|
|||
dragListOK = true;
|
||||
}
|
||||
|
||||
int mouseOver = curFeature;
|
||||
if (curFeature == -1) mouseOver = GetHighlightedFeature();
|
||||
FeatureType* mouseOver = curFeature ? curFeature : GetHighlightedFeature();
|
||||
|
||||
for (size_t i=0;i<features.size();i++) {
|
||||
SetFillColour(colour[(signed)i == mouseOver ? 2 : 1],0.6f);
|
||||
for (FeatureCIter cur = features.begin(); cur != features.end(); ++cur) {
|
||||
int fill = &*cur == mouseOver ? 2 :
|
||||
cur->selected ? 3 :
|
||||
1;
|
||||
SetFillColour(colour[fill],0.6f);
|
||||
SetLineColour(colour[0],1.0f,2);
|
||||
features[i].Draw(*this);
|
||||
cur->Draw(*this);
|
||||
}
|
||||
}
|
||||
|
||||
/// @brief Refresh
|
||||
template<class FeatureType>
|
||||
void VisualTool<FeatureType>::Refresh() {
|
||||
frame_n = VideoContext::Get()->GetFrameN();
|
||||
if (!dragging) dragListOK = false;
|
||||
if (externalChange) dragListOK = false;
|
||||
DoRefresh();
|
||||
}
|
||||
|
||||
template<class FeatureType>
|
||||
void VisualTool<FeatureType>::ClearSelection() {
|
||||
for (SelFeatureIter cur = selFeatures.begin(); cur != selFeatures.end(); ++cur) {
|
||||
(*cur)->selected = false;
|
||||
}
|
||||
selFeatures.clear();
|
||||
}
|
||||
|
||||
/// @brief Get position of line
|
||||
/// @param diag
|
||||
/// @param x
|
||||
/// @param y
|
||||
template<class FeatureType>
|
||||
void VisualTool<FeatureType>::GetLinePosition(AssDialogue *diag,int &x, int &y) {
|
||||
int orgx=0,orgy=0;
|
||||
int orgx,orgy;
|
||||
GetLinePosition(diag,x,y,orgx,orgy);
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@
|
|||
|
||||
#ifndef AGI_PRE
|
||||
#include <vector>
|
||||
#include "boost/shared_ptr.hpp"
|
||||
|
||||
#include <wx/log.h>
|
||||
#include <wx/event.h>
|
||||
|
@ -76,56 +75,38 @@ public:
|
|||
template<class FeatureType>
|
||||
class VisualTool : public IVisualTool {
|
||||
private:
|
||||
/// DOCME
|
||||
int dragStartX; /// Starting x coordinate of the current drag, if any
|
||||
int dragStartY; /// Starting y coordinate of the current drag, if any
|
||||
|
||||
/// DOCME
|
||||
/// @brief Get the topmost visual feature under the mouse, or NULL if none are under the mouse
|
||||
FeatureType* GetHighlightedFeature();
|
||||
|
||||
/// DOCME
|
||||
typedef typename std::list<FeatureType*>::iterator SelFeatureIter;
|
||||
typedef typename std::list<FeatureType>::iterator FeatureIter;
|
||||
typedef typename std::list<FeatureType>::const_iterator FeatureCIter;
|
||||
|
||||
/// DOCME
|
||||
int dragStartX,dragStartY,dragOrigX,dragOrigY;
|
||||
int GetHighlightedFeature();
|
||||
std::list<FeatureType*> selFeatures; /// Currently selected visual features
|
||||
|
||||
bool externalChange; /// Only invalid drag lists when refreshing due to external changes
|
||||
bool selChanged; /// Has the selection already been changed in the current click?
|
||||
protected:
|
||||
/// DOCME
|
||||
VideoDisplay *parent;
|
||||
VideoDisplay *parent; /// VideoDisplay which this belongs to, used to frame conversion
|
||||
bool holding; /// Is a hold currently in progress?
|
||||
AssDialogue *curDiag; /// Active dialogue line for a hold; only valid when holding = true
|
||||
bool dragging; /// Is a drag currently in progress?
|
||||
|
||||
/// DOCME
|
||||
bool holding;
|
||||
FeatureType* curFeature; /// Topmost feature under the mouse; only valid during a drag?
|
||||
std::list<FeatureType> features; /// List of features which are drawn and can be clicked on
|
||||
bool dragListOK; /// Do the features not need to be regenerated?
|
||||
|
||||
/// DOCME
|
||||
AssDialogue *curDiag;
|
||||
int frame_n; /// Current frame number
|
||||
VideoState const& video; /// Mouse and video information
|
||||
|
||||
/// DOCME
|
||||
bool dragging;
|
||||
|
||||
/// DOCME
|
||||
int curFeature;
|
||||
|
||||
/// DOCME
|
||||
std::vector<FeatureType> features;
|
||||
|
||||
/// DOCME
|
||||
bool dragListOK;
|
||||
|
||||
/// DOCME
|
||||
int frame_n;
|
||||
|
||||
VideoState const& video;
|
||||
|
||||
/// DOCME
|
||||
bool leftClick;
|
||||
|
||||
/// DOCME
|
||||
bool leftDClick;
|
||||
|
||||
/// DOCME
|
||||
bool shiftDown;
|
||||
|
||||
/// DOCME
|
||||
bool ctrlDown;
|
||||
|
||||
/// DOCME
|
||||
bool altDown;
|
||||
bool leftClick; /// Is a left click event currently being processed?
|
||||
bool leftDClick; /// Is a left double click event currently being processed?
|
||||
bool shiftDown; /// Is shift down?
|
||||
bool ctrlDown; /// Is ctrl down?
|
||||
bool altDown; /// Is alt down?
|
||||
|
||||
void GetLinePosition(AssDialogue *diag,int &x,int &y);
|
||||
void GetLinePosition(AssDialogue *diag,int &x,int &y,int &orgx,int &orgy);
|
||||
|
@ -136,58 +117,63 @@ protected:
|
|||
wxString GetLineVectorClip(AssDialogue *diag,int &scale,bool &inverse);
|
||||
void SetOverride(AssDialogue* line, wxString tag, wxString value);
|
||||
|
||||
/// @brief Get the dialogue line currently in the edit box
|
||||
/// @return NULL if the line is not active on the current frame
|
||||
AssDialogue *GetActiveDialogueLine();
|
||||
void DrawAllFeatures();
|
||||
void Commit(bool full=false);
|
||||
|
||||
/// @brief DOCME
|
||||
///
|
||||
/// @brief Called when a hold is begun
|
||||
/// @return Should the hold actually happen?
|
||||
virtual bool InitializeHold() { return false; }
|
||||
|
||||
/// @brief DOCME
|
||||
///
|
||||
virtual void UpdateHold() {}
|
||||
/// @brief Called on every mouse event during a hold
|
||||
virtual void UpdateHold() { }
|
||||
|
||||
/// @brief DOCME
|
||||
/// @return
|
||||
///
|
||||
virtual void CommitHold() {}
|
||||
/// @brief Called at the end of a hold
|
||||
virtual void CommitHold() { }
|
||||
|
||||
/// @brief DOCME
|
||||
///
|
||||
/// @brief Called when the feature list needs to be (re)generated
|
||||
virtual void PopulateFeatureList() { }
|
||||
|
||||
/// @brief DOCME
|
||||
/// @param feature
|
||||
///
|
||||
virtual bool InitializeDrag(FeatureType &feature) { return true; }
|
||||
/// @brief Called at the beginning of a drag
|
||||
/// @param feature The visual feature clicked on
|
||||
/// @return Should the drag happen?
|
||||
virtual bool InitializeDrag(FeatureType* feature) { return true; }
|
||||
|
||||
/// @brief DOCME
|
||||
/// @param feature
|
||||
///
|
||||
virtual void UpdateDrag(FeatureType &feature) {}
|
||||
/// @brief Called on every mouse event during a drag
|
||||
/// @param feature The current feature to process; not necessarily the one clicked on
|
||||
virtual void UpdateDrag(FeatureType* feature) { }
|
||||
|
||||
/// @brief DOCME
|
||||
/// @param feature
|
||||
///
|
||||
virtual void CommitDrag(FeatureType &feature) {}
|
||||
// @brief Called at the end of a drag
|
||||
virtual void CommitDrag(FeatureType* feature) { }
|
||||
|
||||
/// @brief DOCME
|
||||
///
|
||||
virtual void DoRefresh() {}
|
||||
/// @brief Called when there's stuff
|
||||
virtual void DoRefresh() { }
|
||||
|
||||
/// @brief Must be called before removing entries from features
|
||||
void ClearSelection();
|
||||
|
||||
public:
|
||||
/// @brief Handler for all mouse events
|
||||
/// @param event Shockingly enough, the mouse event
|
||||
void OnMouseEvent(wxMouseEvent &event);
|
||||
|
||||
/// @brief DOCME
|
||||
/// @param event
|
||||
///
|
||||
virtual void OnSubTool(wxCommandEvent &) {}
|
||||
/// @brief Event handler for the subtoolbar
|
||||
virtual void OnSubTool(wxCommandEvent &) { }
|
||||
/// @brief Called when there's stuff
|
||||
virtual void Update() { };
|
||||
/// @brief Draw stuff
|
||||
virtual void Draw()=0;
|
||||
/// @brief Called when there's stuff
|
||||
void Refresh();
|
||||
|
||||
/// @brief Constructor
|
||||
/// @param parent The VideoDisplay to use for coordinate conversion
|
||||
/// @param video Video and mouse information passing blob
|
||||
VisualTool(VideoDisplay *parent, VideoState const& video);
|
||||
|
||||
/// @brief Destructor
|
||||
virtual ~VisualTool();
|
||||
};
|
||||
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
/// @brief Rectangular clipping visual typesetting tool
|
||||
/// @ingroup visual_ts
|
||||
|
||||
///////////
|
||||
// Headers
|
||||
#include "config.h"
|
||||
|
||||
#include "ass_dialogue.h"
|
||||
|
@ -48,7 +46,7 @@
|
|||
/// @brief Constructor
|
||||
/// @param _parent
|
||||
VisualToolClip::VisualToolClip(VideoDisplay *parent, VideoState const& video, wxToolBar *)
|
||||
: VisualTool(parent, video)
|
||||
: VisualTool<ClipCorner>(parent, video)
|
||||
, curX1(0)
|
||||
, curY1(0)
|
||||
, curX2(video.w)
|
||||
|
@ -142,47 +140,52 @@ void VisualToolClip::CommitHold() {
|
|||
void VisualToolClip::PopulateFeatureList() {
|
||||
// Clear
|
||||
if (features.size() != 4) {
|
||||
ClearSelection();
|
||||
features.clear();
|
||||
features.resize(4);
|
||||
int i = 0;
|
||||
for (std::list<ClipCorner>::iterator cur = features.begin(); cur != features.end(); ++cur, ++i) {
|
||||
feat[i] = &*cur;
|
||||
}
|
||||
}
|
||||
|
||||
// Top-left
|
||||
int i = 0;
|
||||
features[i].x = curX1;
|
||||
features[i].y = curY1;
|
||||
features[i].horiz = &features[1];
|
||||
features[i].vert = &features[2];
|
||||
features[i].type = DRAG_SMALL_CIRCLE;
|
||||
feat[i]->x = curX1;
|
||||
feat[i]->y = curY1;
|
||||
feat[i]->horiz = feat[1];
|
||||
feat[i]->vert = feat[2];
|
||||
feat[i]->type = DRAG_SMALL_CIRCLE;
|
||||
i++;
|
||||
|
||||
// Top-right
|
||||
features[i].x = curX2;
|
||||
features[i].y = curY1;
|
||||
features[i].horiz = &features[0];
|
||||
features[i].vert = &features[3];
|
||||
features[i].type = DRAG_SMALL_CIRCLE;
|
||||
feat[i]->x = curX2;
|
||||
feat[i]->y = curY1;
|
||||
feat[i]->horiz = feat[0];
|
||||
feat[i]->vert = feat[3];
|
||||
feat[i]->type = DRAG_SMALL_CIRCLE;
|
||||
i++;
|
||||
|
||||
// Bottom-left
|
||||
features[i].x = curX1;
|
||||
features[i].y = curY2;
|
||||
features[i].horiz = &features[3];
|
||||
features[i].vert = &features[0];
|
||||
features[i].type = DRAG_SMALL_CIRCLE;
|
||||
feat[i]->x = curX1;
|
||||
feat[i]->y = curY2;
|
||||
feat[i]->horiz = feat[3];
|
||||
feat[i]->vert = feat[0];
|
||||
feat[i]->type = DRAG_SMALL_CIRCLE;
|
||||
i++;
|
||||
|
||||
// Bottom-right
|
||||
features[i].x = curX2;
|
||||
features[i].y = curY2;
|
||||
features[i].horiz = &features[2];
|
||||
features[i].vert = &features[1];
|
||||
features[i].type = DRAG_SMALL_CIRCLE;
|
||||
feat[i]->x = curX2;
|
||||
feat[i]->y = curY2;
|
||||
feat[i]->horiz = feat[2];
|
||||
feat[i]->vert = feat[1];
|
||||
feat[i]->type = DRAG_SMALL_CIRCLE;
|
||||
i++;
|
||||
}
|
||||
|
||||
/// @brief Initialize
|
||||
/// @param feature
|
||||
bool VisualToolClip::InitializeDrag(ClipCorner &feature) {
|
||||
bool VisualToolClip::InitializeDrag(ClipCorner*) {
|
||||
curDiag = GetActiveDialogueLine();
|
||||
curDiag->StripTag(L"\\clip");
|
||||
curDiag->StripTag(L"\\iclip");
|
||||
|
@ -191,16 +194,16 @@ bool VisualToolClip::InitializeDrag(ClipCorner &feature) {
|
|||
|
||||
/// @brief Update drag
|
||||
/// @param feature
|
||||
void VisualToolClip::UpdateDrag(ClipCorner &feature) {
|
||||
void VisualToolClip::UpdateDrag(ClipCorner* feature) {
|
||||
// Update brothers
|
||||
feature.horiz->y = feature.y;
|
||||
feature.vert->x = feature.x;
|
||||
feature->horiz->y = feature->y;
|
||||
feature->vert->x = feature->x;
|
||||
|
||||
// Get "cur" from features
|
||||
curX1 = features[0].x;
|
||||
curX2 = features[3].x;
|
||||
curY1 = features[0].y;
|
||||
curY2 = features[3].y;
|
||||
curX1 = feat[0]->x;
|
||||
curX2 = feat[3]->x;
|
||||
curY1 = feat[0]->y;
|
||||
curY2 = feat[3]->y;
|
||||
|
||||
// Make sure p1 < p2
|
||||
if (curX1 > curX2) IntSwap(curX1,curX2);
|
||||
|
@ -209,6 +212,6 @@ void VisualToolClip::UpdateDrag(ClipCorner &feature) {
|
|||
|
||||
/// @brief Done dragging
|
||||
/// @param feature
|
||||
void VisualToolClip::CommitDrag(ClipCorner &feature) {
|
||||
void VisualToolClip::CommitDrag(ClipCorner*) {
|
||||
CommitHold();
|
||||
}
|
||||
|
|
|
@ -75,6 +75,8 @@ private:
|
|||
/// DOCME
|
||||
bool inverse;
|
||||
|
||||
ClipCorner* feat[4];
|
||||
|
||||
|
||||
/// @brief DOCME
|
||||
/// @return
|
||||
|
@ -87,9 +89,9 @@ private:
|
|||
/// @brief DOCME
|
||||
///
|
||||
void PopulateFeatureList();
|
||||
bool InitializeDrag(ClipCorner &feature);
|
||||
void UpdateDrag(ClipCorner &feature);
|
||||
void CommitDrag(ClipCorner &feature);
|
||||
bool InitializeDrag(ClipCorner* feature);
|
||||
void UpdateDrag(ClipCorner* feature);
|
||||
void CommitDrag(ClipCorner* feature);
|
||||
|
||||
public:
|
||||
VisualToolClip(VideoDisplay *parent, VideoState const& video, wxToolBar *);
|
||||
|
|
|
@ -33,8 +33,6 @@
|
|||
/// @brief Crosshair double-click-to-position visual typesetting tool
|
||||
/// @ingroup visual_ts
|
||||
|
||||
///////////
|
||||
// Headers
|
||||
#include "config.h"
|
||||
|
||||
#include "ass_file.h"
|
||||
|
@ -48,7 +46,7 @@
|
|||
/// @brief Constructor
|
||||
/// @param _parent
|
||||
VisualToolCross::VisualToolCross(VideoDisplay *parent, VideoState const& video, wxToolBar *)
|
||||
: VisualTool(parent, video)
|
||||
: VisualTool<VisualDraggableFeature>(parent, video)
|
||||
{
|
||||
}
|
||||
VisualToolCross::~VisualToolCross() { }
|
||||
|
|
|
@ -54,7 +54,7 @@ enum {
|
|||
/// @param _parent
|
||||
/// @param toolBar
|
||||
VisualToolDrag::VisualToolDrag(VideoDisplay *parent, VideoState const& video, wxToolBar * toolBar)
|
||||
: VisualTool(parent, video)
|
||||
: VisualTool<VisualToolDragDraggableFeature>(parent, video)
|
||||
, toolBar(toolBar)
|
||||
, toggleMoveOnMove(true)
|
||||
{
|
||||
|
@ -127,10 +127,10 @@ void VisualToolDrag::Draw() {
|
|||
DrawAllFeatures();
|
||||
|
||||
// Draw arrows
|
||||
for (size_t i=0;i<features.size();i++) {
|
||||
if (features[i].type == DRAG_BIG_SQUARE) continue;
|
||||
VisualDraggableFeature *p2 = &features[i];
|
||||
VisualDraggableFeature *p1 = &features[features[i].parent];
|
||||
for (std::list<VisualToolDragDraggableFeature>::iterator cur = features.begin(); cur != features.end(); ++cur) {
|
||||
if (cur->type == DRAG_BIG_SQUARE) continue;
|
||||
VisualDraggableFeature *p2 = &*cur;
|
||||
VisualDraggableFeature *p1 = cur->parent;
|
||||
|
||||
// Has arrow?
|
||||
bool hasArrow = p2->type == DRAG_BIG_CIRCLE;
|
||||
|
@ -175,6 +175,7 @@ void VisualToolDrag::Draw() {
|
|||
|
||||
/// @brief Populate list
|
||||
void VisualToolDrag::PopulateFeatureList() {
|
||||
ClearSelection();
|
||||
features.clear();
|
||||
|
||||
// Get video data
|
||||
|
@ -209,7 +210,7 @@ void VisualToolDrag::PopulateFeatureList() {
|
|||
feat.line = diag;
|
||||
feat.lineN = i;
|
||||
features.push_back(feat);
|
||||
feat.parent = features.size() - 1;
|
||||
feat.parent = &features.back();
|
||||
|
||||
// Create move destination feature
|
||||
if (hasMove) {
|
||||
|
@ -221,7 +222,7 @@ void VisualToolDrag::PopulateFeatureList() {
|
|||
feat.line = diag;
|
||||
feat.lineN = i;
|
||||
features.push_back(feat);
|
||||
features[feat.parent].parent = features.size() - 1;
|
||||
feat.parent->parent = &features.back();
|
||||
}
|
||||
// Create org feature
|
||||
if (torgx != x1 || torgy != y1) {
|
||||
|
@ -241,25 +242,25 @@ void VisualToolDrag::PopulateFeatureList() {
|
|||
|
||||
/// @brief Update drag
|
||||
/// @param feature
|
||||
void VisualToolDrag::UpdateDrag(VisualToolDragDraggableFeature &feature) {
|
||||
void VisualToolDrag::UpdateDrag(VisualToolDragDraggableFeature* feature) {
|
||||
// Update "time" to reflect the time of the frame in which the feature is being dragged
|
||||
int time = VFR_Output.GetTimeAtFrame(frame_n,true,true);
|
||||
feature.time = MID(0,time - feature.line->Start.GetMS(),feature.line->End.GetMS()-feature.line->Start.GetMS());
|
||||
feature->time = MID(0,time - feature->line->Start.GetMS(),feature->line->End.GetMS()-feature->line->Start.GetMS());
|
||||
}
|
||||
|
||||
/// @brief Commit drag
|
||||
/// @param feature
|
||||
void VisualToolDrag::CommitDrag(VisualToolDragDraggableFeature &feature) {
|
||||
void VisualToolDrag::CommitDrag(VisualToolDragDraggableFeature* feature) {
|
||||
// Origin
|
||||
if (feature.type == DRAG_BIG_TRIANGLE) {
|
||||
int x = feature.x;
|
||||
int y = feature.y;
|
||||
if (feature->type == DRAG_BIG_TRIANGLE) {
|
||||
int x = feature->x;
|
||||
int y = feature->y;
|
||||
parent->ToScriptCoords(&x, &y);
|
||||
SetOverride(feature.line, L"\\org",wxString::Format(L"(%i,%i)",x,y));
|
||||
SetOverride(feature->line, L"\\org",wxString::Format(L"(%i,%i)",x,y));
|
||||
return;
|
||||
}
|
||||
|
||||
VisualToolDragDraggableFeature *p = feature->parent > -1 ? &features[feature->parent] : NULL;
|
||||
VisualToolDragDraggableFeature *p = feature->parent;
|
||||
if (feature->type == DRAG_BIG_CIRCLE) {
|
||||
std::swap(feature, p);
|
||||
}
|
||||
|
@ -270,7 +271,7 @@ void VisualToolDrag::CommitDrag(VisualToolDragDraggableFeature &feature) {
|
|||
|
||||
// Position
|
||||
if (!p) {
|
||||
SetOverride(feature.line, L"\\pos", wxString::Format(L"(%i,%i)", x1, y1));
|
||||
SetOverride(feature->line, L"\\pos", wxString::Format(L"(%i,%i)", x1, y1));
|
||||
}
|
||||
// Move
|
||||
else {
|
||||
|
|
|
@ -47,11 +47,11 @@
|
|||
class VisualToolDragDraggableFeature : public VisualDraggableFeature {
|
||||
public:
|
||||
int time;
|
||||
int parent;
|
||||
VisualToolDragDraggableFeature* parent;
|
||||
VisualToolDragDraggableFeature()
|
||||
: VisualDraggableFeature()
|
||||
, time(0)
|
||||
, parent(-1)
|
||||
, parent(NULL)
|
||||
{ }
|
||||
};
|
||||
|
||||
|
@ -73,8 +73,8 @@ private:
|
|||
///
|
||||
bool CanDrag() { return true; }
|
||||
void PopulateFeatureList();
|
||||
void UpdateDrag(VisualToolDragDraggableFeature &feature);
|
||||
void CommitDrag(VisualToolDragDraggableFeature &feature);
|
||||
void UpdateDrag(VisualToolDragDraggableFeature* feature);
|
||||
void CommitDrag(VisualToolDragDraggableFeature* feature);
|
||||
|
||||
void UpdateToggleButtons();
|
||||
void DoRefresh();
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
/// @brief Constructor
|
||||
/// @param _parent
|
||||
VisualToolRotateXY::VisualToolRotateXY(VideoDisplay *parent, VideoState const& video, wxToolBar *)
|
||||
: VisualTool(parent, video)
|
||||
: VisualTool<VisualDraggableFeature>(parent, video)
|
||||
{
|
||||
DoRefresh();
|
||||
}
|
||||
|
@ -230,18 +230,18 @@ void VisualToolRotateXY::PopulateFeatureList() {
|
|||
|
||||
/// @brief Update dragging of \\org
|
||||
/// @param feature
|
||||
void VisualToolRotateXY::UpdateDrag(VisualDraggableFeature &feature) {
|
||||
orgx = feature.x;
|
||||
orgy = feature.y;
|
||||
void VisualToolRotateXY::UpdateDrag(VisualDraggableFeature* feature) {
|
||||
orgx = feature->x;
|
||||
orgy = feature->y;
|
||||
}
|
||||
|
||||
/// @brief Commit dragging of \\org
|
||||
/// @param feature
|
||||
void VisualToolRotateXY::CommitDrag(VisualDraggableFeature &feature) {
|
||||
int x = feature.x;
|
||||
int y = feature.y;
|
||||
void VisualToolRotateXY::CommitDrag(VisualDraggableFeature* feature) {
|
||||
int x = feature->x;
|
||||
int y = feature->y;
|
||||
parent->ToScriptCoords(&x, &y);
|
||||
SetOverride(feature.line, L"\\org",wxString::Format(L"(%i,%i)",x,y));
|
||||
SetOverride(feature->line, L"\\org",wxString::Format(L"(%i,%i)",x,y));
|
||||
}
|
||||
|
||||
/// @brief Refresh
|
||||
|
|
|
@ -81,8 +81,8 @@ private:
|
|||
/// @brief DOCME
|
||||
///
|
||||
void PopulateFeatureList();
|
||||
void UpdateDrag(VisualDraggableFeature &feature);
|
||||
void CommitDrag(VisualDraggableFeature &feature);
|
||||
void UpdateDrag(VisualDraggableFeature* feature);
|
||||
void CommitDrag(VisualDraggableFeature* feature);
|
||||
|
||||
void DoRefresh();
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
/// @brief Constructor
|
||||
/// @param _parent
|
||||
VisualToolRotateZ::VisualToolRotateZ(VideoDisplay *parent, VideoState const& video, wxToolBar *)
|
||||
: VisualTool(parent, video)
|
||||
: VisualTool<VisualDraggableFeature>(parent, video)
|
||||
{
|
||||
DoRefresh();
|
||||
}
|
||||
|
@ -144,7 +144,7 @@ void VisualToolRotateZ::Draw() {
|
|||
glPopMatrix();
|
||||
|
||||
// Draw line to mouse
|
||||
if (!dragging && curFeature == -1) {
|
||||
if (!dragging && !curFeature) {
|
||||
SetLineColour(colour[0]);
|
||||
DrawLine(dx,dy,video.x,video.y);
|
||||
}
|
||||
|
@ -197,18 +197,18 @@ void VisualToolRotateZ::PopulateFeatureList() {
|
|||
|
||||
/// @brief Update dragging of \\org
|
||||
/// @param feature
|
||||
void VisualToolRotateZ::UpdateDrag(VisualDraggableFeature &feature) {
|
||||
orgx = feature.x;
|
||||
orgy = feature.y;
|
||||
void VisualToolRotateZ::UpdateDrag(VisualDraggableFeature* feature) {
|
||||
orgx = feature->x;
|
||||
orgy = feature->y;
|
||||
}
|
||||
|
||||
/// @brief Commit dragging of \\org
|
||||
/// @param feature
|
||||
void VisualToolRotateZ::CommitDrag(VisualDraggableFeature &feature) {
|
||||
int x = feature.x;
|
||||
int y = feature.y;
|
||||
void VisualToolRotateZ::CommitDrag(VisualDraggableFeature* feature) {
|
||||
int x = feature->x;
|
||||
int y = feature->y;
|
||||
parent->ToScriptCoords(&x, &y);
|
||||
SetOverride(feature.line, L"\\org",wxString::Format(L"(%i,%i)",x,y));
|
||||
SetOverride(feature->line, L"\\org",wxString::Format(L"(%i,%i)",x,y));
|
||||
}
|
||||
|
||||
/// @brief Refresh
|
||||
|
|
|
@ -79,8 +79,8 @@ private:
|
|||
/// @brief DOCME
|
||||
///
|
||||
void PopulateFeatureList();
|
||||
void UpdateDrag(VisualDraggableFeature &feature);
|
||||
void CommitDrag(VisualDraggableFeature &feature);
|
||||
void UpdateDrag(VisualDraggableFeature* feature);
|
||||
void CommitDrag(VisualDraggableFeature* feature);
|
||||
|
||||
void DoRefresh();
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
/// @brief Constructor
|
||||
/// @param _parent
|
||||
VisualToolScale::VisualToolScale(VideoDisplay *parent, VideoState const& video, wxToolBar *)
|
||||
: VisualTool(parent, video)
|
||||
: VisualTool<VisualDraggableFeature>(parent, video)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -80,7 +80,9 @@ enum {
|
|||
/// @param parent
|
||||
/// @param _toolBar
|
||||
VisualToolVectorClip::VisualToolVectorClip(VideoDisplay *parent, VideoState const& video, wxToolBar * toolBar)
|
||||
: VisualTool(parent, video), toolBar(toolBar), spline(*parent)
|
||||
: VisualTool<VisualToolVectorClipDraggableFeature>(parent, video)
|
||||
, toolBar(toolBar)
|
||||
, spline(*parent)
|
||||
{
|
||||
DoRefresh();
|
||||
mode = 0;
|
||||
|
@ -168,7 +170,7 @@ void VisualToolVectorClip::Draw() {
|
|||
SetLineColour(colour[3],1.0f,2);
|
||||
int col = 3;
|
||||
for (size_t i=1;i<points.size();i++) {
|
||||
int useCol = pointCurve[i] == highCurve && curFeature == -1 ? 2 : 3;
|
||||
int useCol = pointCurve[i] == highCurve && !curFeature ? 2 : 3;
|
||||
if (col != useCol) {
|
||||
col = useCol;
|
||||
SetLineColour(colour[col],1.0f,2);
|
||||
|
@ -205,6 +207,7 @@ void VisualToolVectorClip::Draw() {
|
|||
/// @brief Populate feature list
|
||||
void VisualToolVectorClip::PopulateFeatureList() {
|
||||
// Clear
|
||||
ClearSelection();
|
||||
features.clear();
|
||||
VisualToolVectorClipDraggableFeature feat;
|
||||
|
||||
|
@ -262,27 +265,27 @@ void VisualToolVectorClip::PopulateFeatureList() {
|
|||
|
||||
/// @brief Update
|
||||
/// @param feature
|
||||
void VisualToolVectorClip::UpdateDrag(VisualToolVectorClipDraggableFeature &feature) {
|
||||
spline.MovePoint(feature.index,feature.point,wxPoint(feature.x,feature.y));
|
||||
void VisualToolVectorClip::UpdateDrag(VisualToolVectorClipDraggableFeature* feature) {
|
||||
spline.MovePoint(feature->index,feature->point,wxPoint(feature->x,feature->y));
|
||||
}
|
||||
|
||||
/// @brief Commit
|
||||
/// @param feature
|
||||
void VisualToolVectorClip::CommitDrag(VisualToolVectorClipDraggableFeature &feature) {
|
||||
void VisualToolVectorClip::CommitDrag(VisualToolVectorClipDraggableFeature* feature) {
|
||||
SetOverride(GetActiveDialogueLine(), inverse ? L"\\iclip" : L"\\clip", L"(" + spline.EncodeToASS() + L")");
|
||||
}
|
||||
|
||||
/// @brief Clicked a feature
|
||||
/// @param feature
|
||||
/// @return
|
||||
bool VisualToolVectorClip::InitializeDrag(VisualToolVectorClipDraggableFeature &feature) {
|
||||
bool VisualToolVectorClip::InitializeDrag(VisualToolVectorClipDraggableFeature* feature) {
|
||||
// Delete a control point
|
||||
if (mode == 5) {
|
||||
int i = 0;
|
||||
for (std::list<SplineCurve>::iterator cur=spline.curves.begin();cur!=spline.curves.end();i++,cur++) {
|
||||
if (i == feature.index) {
|
||||
if (i == feature->index) {
|
||||
// Update next
|
||||
if (i != 0 || feature.point != 0) {
|
||||
if (i != 0 || feature->point != 0) {
|
||||
std::list<SplineCurve>::iterator next = cur;
|
||||
next++;
|
||||
if (next != spline.curves.end()) next->p1 = cur->p1;
|
||||
|
@ -291,7 +294,7 @@ bool VisualToolVectorClip::InitializeDrag(VisualToolVectorClipDraggableFeature &
|
|||
// Erase and save changes
|
||||
spline.curves.erase(cur);
|
||||
CommitDrag(feature);
|
||||
curFeature = -1;
|
||||
curFeature = NULL;
|
||||
Commit(true);
|
||||
return false;
|
||||
}
|
||||
|
@ -387,6 +390,7 @@ bool VisualToolVectorClip::InitializeHold() {
|
|||
|
||||
// Freehand
|
||||
if (mode == 6 || mode == 7) {
|
||||
ClearSelection();
|
||||
features.clear();
|
||||
spline.curves.clear();
|
||||
lastX = INT_MIN;
|
||||
|
|
|
@ -92,9 +92,9 @@ private:
|
|||
|
||||
|
||||
void PopulateFeatureList();
|
||||
void UpdateDrag(VisualToolVectorClipDraggableFeature &feature);
|
||||
void CommitDrag(VisualToolVectorClipDraggableFeature &feature);
|
||||
bool InitializeDrag(VisualToolVectorClipDraggableFeature &feature);
|
||||
void UpdateDrag(VisualToolVectorClipDraggableFeature* feature);
|
||||
void CommitDrag(VisualToolVectorClipDraggableFeature* feature);
|
||||
bool InitializeDrag(VisualToolVectorClipDraggableFeature* feature);
|
||||
|
||||
void DoRefresh();
|
||||
|
||||
|
|
Loading…
Reference in a new issue