2013-09-17 20:13:52 +02:00
|
|
|
// Copyright (c) 2013, Thomas Goyne <plorkyeran@aegisub.org>
|
2007-01-08 22:11:06 +01: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-01-08 22:11:06 +01: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-01-08 22:11:06 +01:00
|
|
|
//
|
2009-07-29 07:43:02 +02:00
|
|
|
// Aegisub Project http://www.aegisub.org/
|
|
|
|
|
|
|
|
/// @file visual_tool.h
|
|
|
|
/// @see visual_tool.cpp
|
|
|
|
/// @ingroup visual_ts
|
2007-01-08 22:11:06 +01:00
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2007-01-21 07:30:19 +01:00
|
|
|
#include "gl_wrap.h"
|
2011-11-06 18:18:20 +01:00
|
|
|
#include "vector2d.h"
|
2007-01-21 07:30:19 +01:00
|
|
|
|
2013-09-17 20:13:52 +02:00
|
|
|
#include <libaegisub/owning_intrusive_list.h>
|
|
|
|
#include <libaegisub/signal.h>
|
|
|
|
|
|
|
|
#include <set>
|
|
|
|
|
2007-01-08 22:11:06 +01:00
|
|
|
class AssDialogue;
|
2011-01-16 08:17:08 +01:00
|
|
|
class VideoDisplay;
|
2014-05-23 00:40:16 +02:00
|
|
|
class wxMouseCaptureLostEvent;
|
|
|
|
class wxMouseEvent;
|
2011-11-06 18:18:20 +01:00
|
|
|
class wxToolBar;
|
2010-06-04 05:07:33 +02:00
|
|
|
namespace agi {
|
2011-01-16 08:17:08 +01:00
|
|
|
struct Context;
|
2010-06-04 05:07:33 +02:00
|
|
|
class OptionValue;
|
|
|
|
}
|
2007-07-04 06:24:47 +02:00
|
|
|
|
2011-11-06 18:18:20 +01:00
|
|
|
/// @class VisualToolBase
|
|
|
|
/// @brief Base class for visual tools containing all functionality that doesn't interact with features
|
|
|
|
///
|
|
|
|
/// This is required so that visual tools can be used polymorphically, as
|
|
|
|
/// different VisualTool<T>s are unrelated types otherwise. In addition, as much
|
|
|
|
/// functionality as possible is implemented here to avoid having four copies
|
|
|
|
/// of each method for no good reason (and four times as many error messages)
|
2012-10-05 05:22:54 +02:00
|
|
|
class VisualToolBase {
|
2011-11-06 18:18:20 +01:00
|
|
|
void OnCommit(int type);
|
|
|
|
void OnSeek(int new_frame);
|
|
|
|
|
|
|
|
void OnMouseCaptureLost(wxMouseCaptureLostEvent &);
|
|
|
|
|
|
|
|
/// @brief Get the dialogue line currently in the edit box
|
2012-11-13 17:51:01 +01:00
|
|
|
/// @return nullptr if the line is not active on the current frame
|
2011-11-06 18:18:20 +01:00
|
|
|
AssDialogue *GetActiveDialogueLine();
|
|
|
|
|
|
|
|
// SubtitleSelectionListener implementation
|
|
|
|
void OnActiveLineChanged(AssDialogue *new_line);
|
|
|
|
|
|
|
|
// Below here are the virtuals that must be implemented
|
|
|
|
|
|
|
|
/// Called when the script, video or screen resolutions change
|
|
|
|
virtual void OnCoordinateSystemsChanged() { DoRefresh(); }
|
|
|
|
|
|
|
|
/// Called when the file is changed by something other than a visual tool
|
|
|
|
virtual void OnFileChanged() { DoRefresh(); }
|
|
|
|
|
|
|
|
/// Called when the frame number changes
|
|
|
|
virtual void OnFrameChanged() { }
|
|
|
|
|
|
|
|
/// Called when the active line changes
|
|
|
|
virtual void OnLineChanged() { DoRefresh(); }
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2011-11-06 18:18:20 +01:00
|
|
|
/// Generic refresh to simplify tools which have no interesting state and
|
|
|
|
/// can simply do do the same thing for any external change (i.e. most of
|
|
|
|
/// them). Called only by the above virtual methods.
|
|
|
|
virtual void DoRefresh() { }
|
2007-07-07 07:51:18 +02:00
|
|
|
|
2010-05-20 10:55:46 +02:00
|
|
|
protected:
|
2014-05-22 01:23:28 +02:00
|
|
|
std::vector<agi::signal::Connection> connections;
|
2012-10-05 05:22:54 +02:00
|
|
|
|
2011-11-06 18:18:20 +01:00
|
|
|
OpenGLWrapper gl;
|
|
|
|
|
|
|
|
/// Called when the user double-clicks
|
|
|
|
virtual void OnDoubleClick() { }
|
|
|
|
|
2010-05-20 10:55:46 +02:00
|
|
|
static const wxColour colour[4];
|
2011-11-06 18:18:20 +01:00
|
|
|
|
|
|
|
agi::Context *c;
|
|
|
|
VideoDisplay *parent;
|
|
|
|
|
2013-12-12 01:29:48 +01:00
|
|
|
bool holding = false; ///< Is a hold currently in progress?
|
|
|
|
AssDialogue *active_line = nullptr; ///< Active dialogue line; nullptr if it is not visible on the current frame
|
|
|
|
bool dragging = false; ///< Is a drag currently in progress?
|
2011-11-06 18:18:20 +01:00
|
|
|
|
|
|
|
int frame_number; ///< Current frame number
|
|
|
|
|
2013-12-12 01:29:48 +01:00
|
|
|
bool shift_down = false; ///< Is shift down?
|
|
|
|
bool ctrl_down = false; ///< Is ctrl down?
|
|
|
|
bool alt_down = false; ///< Is alt down?
|
2011-11-06 18:18:20 +01:00
|
|
|
|
|
|
|
Vector2D mouse_pos; ///< Last seen mouse position
|
|
|
|
Vector2D drag_start; ///< Mouse position at the beginning of the last drag
|
|
|
|
Vector2D script_res; ///< Script resolution
|
|
|
|
Vector2D video_pos; ///< Top-left corner of the video in the display area
|
|
|
|
Vector2D video_res; ///< Video resolution
|
|
|
|
|
|
|
|
agi::signal::Connection file_changed_connection;
|
2013-12-12 01:29:48 +01:00
|
|
|
int commit_id = -1; ///< Last used commit id for coalescing
|
2011-11-06 18:18:20 +01:00
|
|
|
|
|
|
|
/// @brief Commit the current file state
|
|
|
|
/// @param message Description of changes for undo
|
2013-09-19 01:18:38 +02:00
|
|
|
virtual void Commit(wxString message = wxString());
|
2011-11-06 18:18:20 +01:00
|
|
|
bool IsDisplayed(AssDialogue *line) const;
|
|
|
|
|
|
|
|
/// Get the line's position if it's set, or it's default based on style if not
|
|
|
|
Vector2D GetLinePosition(AssDialogue *diag);
|
|
|
|
/// Get the line's origin if it's set, or Vector2D::Bad() if not
|
|
|
|
Vector2D GetLineOrigin(AssDialogue *diag);
|
|
|
|
bool GetLineMove(AssDialogue *diag, Vector2D &p1, Vector2D &p2, int &t1, int &t2);
|
|
|
|
void GetLineRotation(AssDialogue *diag, float &rx, float &ry, float &rz);
|
2013-12-14 16:45:26 +01:00
|
|
|
void GetLineShear(AssDialogue *diag, float& fax, float& fay);
|
2011-11-06 18:18:20 +01:00
|
|
|
void GetLineScale(AssDialogue *diag, Vector2D &scale);
|
|
|
|
void GetLineClip(AssDialogue *diag, Vector2D &p1, Vector2D &p2, bool &inverse);
|
2013-01-04 16:01:50 +01:00
|
|
|
std::string GetLineVectorClip(AssDialogue *diag, int &scale, bool &inverse);
|
2011-11-06 18:18:20 +01:00
|
|
|
|
2013-01-04 16:01:50 +01:00
|
|
|
void SetOverride(AssDialogue* line, std::string const& tag, std::string const& value);
|
|
|
|
void SetSelectedOverride(std::string const& tag, std::string const& value);
|
2011-11-06 18:18:20 +01:00
|
|
|
|
|
|
|
VisualToolBase(VideoDisplay *parent, agi::Context *context);
|
|
|
|
|
2010-05-20 10:55:46 +02:00
|
|
|
public:
|
2011-11-06 18:18:20 +01:00
|
|
|
/// Convert a point from video to script coordinates
|
|
|
|
Vector2D ToScriptCoords(Vector2D point) const;
|
|
|
|
/// Convert a point from script to video coordinates
|
|
|
|
Vector2D FromScriptCoords(Vector2D point) const;
|
|
|
|
|
|
|
|
// Stuff called by VideoDisplay
|
2010-05-20 10:55:46 +02:00
|
|
|
virtual void OnMouseEvent(wxMouseEvent &event)=0;
|
|
|
|
virtual void Draw()=0;
|
2011-11-06 18:18:20 +01:00
|
|
|
virtual void SetDisplayArea(int x, int y, int w, int h);
|
2011-12-22 22:09:31 +01:00
|
|
|
virtual void SetToolbar(wxToolBar *) { }
|
2014-04-25 19:01:07 +02:00
|
|
|
virtual ~VisualToolBase() = default;
|
2010-05-20 10:55:46 +02:00
|
|
|
};
|
|
|
|
|
2012-12-02 22:08:42 +01:00
|
|
|
/// Visual tool base class containing all common feature-related functionality
|
2010-05-20 10:55:46 +02:00
|
|
|
template<class FeatureType>
|
2014-03-13 04:32:57 +01:00
|
|
|
class VisualTool : public VisualToolBase {
|
2010-06-30 08:29:14 +02:00
|
|
|
protected:
|
2010-07-06 21:33:09 +02:00
|
|
|
typedef FeatureType Feature;
|
2013-09-17 20:13:52 +02:00
|
|
|
typedef agi::owning_intrusive_list<FeatureType> feature_list;
|
2010-11-01 05:36:13 +01:00
|
|
|
|
2011-11-06 18:18:20 +01:00
|
|
|
private:
|
2013-12-12 01:29:48 +01:00
|
|
|
bool sel_changed = false; /// Has the selection already been changed in the current click?
|
2010-06-28 09:13:15 +02:00
|
|
|
|
|
|
|
/// @brief Called when a hold is begun
|
|
|
|
/// @return Should the hold actually happen?
|
|
|
|
virtual bool InitializeHold() { return false; }
|
|
|
|
/// @brief Called on every mouse event during a hold
|
|
|
|
virtual void UpdateHold() { }
|
|
|
|
|
|
|
|
/// @brief Called at the beginning of a drag
|
|
|
|
/// @param feature The visual feature clicked on
|
|
|
|
/// @return Should the drag happen?
|
2013-09-17 20:13:52 +02:00
|
|
|
virtual bool InitializeDrag(FeatureType *feature) { return true; }
|
2010-06-28 09:13:15 +02:00
|
|
|
/// @brief Called on every mouse event during a drag
|
|
|
|
/// @param feature The current feature to process; not necessarily the one clicked on
|
2013-09-17 20:13:52 +02:00
|
|
|
virtual void UpdateDrag(FeatureType *feature) { }
|
2010-06-28 09:13:15 +02:00
|
|
|
|
2010-05-20 10:55:58 +02:00
|
|
|
protected:
|
2013-09-17 20:13:52 +02:00
|
|
|
std::set<FeatureType *> sel_features; ///< Currently selected visual features
|
2011-11-06 18:18:20 +01:00
|
|
|
|
|
|
|
/// Topmost feature under the mouse; generally only valid during a drag
|
2013-12-12 01:29:48 +01:00
|
|
|
FeatureType *active_feature = nullptr;
|
2011-11-06 18:18:20 +01:00
|
|
|
/// List of features which are drawn and can be clicked on
|
|
|
|
/// List is used here for the iterator invalidation properties
|
2013-09-17 20:13:52 +02:00
|
|
|
feature_list features;
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2010-05-26 09:17:39 +02:00
|
|
|
/// Draw all of the features in the list
|
2007-07-01 09:09:37 +02:00
|
|
|
void DrawAllFeatures();
|
2010-06-28 09:13:15 +02:00
|
|
|
|
2010-05-26 09:17:39 +02:00
|
|
|
/// @brief Remove a feature from the selection
|
|
|
|
/// @param i Index in the feature list
|
|
|
|
/// Also deselects lines if all features for that line have been deselected
|
2013-09-17 20:13:52 +02:00
|
|
|
void RemoveSelection(FeatureType *feat);
|
2010-06-28 09:13:15 +02:00
|
|
|
|
|
|
|
/// @brief Set the selection to a single feature, deselecting everything else
|
|
|
|
/// @param i Index in the feature list
|
2013-09-17 20:13:52 +02:00
|
|
|
void SetSelection(FeatureType *feat, bool clear);
|
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
|
|
|
|
2007-01-08 22:11:06 +01:00
|
|
|
public:
|
2010-05-20 10:55:58 +02:00
|
|
|
/// @brief Handler for all mouse events
|
|
|
|
/// @param event Shockingly enough, the mouse event
|
2013-11-21 18:13:36 +01:00
|
|
|
void OnMouseEvent(wxMouseEvent &event) override;
|
Note: This was done using a script! it's far from perfect but 95% of the work has been done already formatting-wise.
Document all functions, class, struct, union, enum, macro, variable, typedefs. This isn't the actual document in itself but empty documentation using any old documentation if it was there.
This was done using exuberant ctags to get tag info, then a TCL script to parse/remove old comments and convert them into Doxygen-style.
Some notes:
* Anything labeled 'DOCME' needs to be documented, @param and @return have been left blank as it would be annoying to delete the 'DOCME' from every one of those.
* Some multiline comments may have been munged into single line comments
* Leave the /// comments above global variables with a space, if they're harder to read then we'll be less likey to use them.
* Enum comments can go after the enumeration itself '[value] /// comment'
* include/aegisub/*.h haven't been converted yet, this will be done in a later commit
* Some documentation blocks are in the wrong place, in the .h when it should be in the .cpp, or vice versa.
See http://devel.aegisub.org/wiki/Doxygen for some details on Doxygen and a 'style guide'.
Originally committed to SVN as r3312.
2009-07-30 00:59:22 +02:00
|
|
|
|
2010-05-20 10:55:58 +02:00
|
|
|
/// @brief Constructor
|
|
|
|
/// @param parent The VideoDisplay to use for coordinate conversion
|
|
|
|
/// @param video Video and mouse information passing blob
|
2011-11-06 18:18:20 +01:00
|
|
|
VisualTool(VideoDisplay *parent, agi::Context *context);
|
2007-01-08 22:11:06 +01:00
|
|
|
};
|