Merge branches 'vector_clip_actions' and 'color_picker_fix2' into feature
This commit is contained in:
commit
8ca6ec1884
13 changed files with 237 additions and 68 deletions
|
@ -19,6 +19,9 @@
|
||||||
|
|
||||||
#include <libaegisub/log.h>
|
#include <libaegisub/log.h>
|
||||||
|
|
||||||
|
#include <boost/algorithm/string/join.hpp>
|
||||||
|
#include "include/aegisub/hotkey.h"
|
||||||
|
|
||||||
#include <wx/intl.h>
|
#include <wx/intl.h>
|
||||||
|
|
||||||
namespace cmd {
|
namespace cmd {
|
||||||
|
@ -32,6 +35,16 @@ namespace cmd {
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxString Command::GetTooltip(std::string ht_context) const {
|
||||||
|
wxString ret = StrHelp();
|
||||||
|
|
||||||
|
std::vector<std::string> hotkeys = hotkey::get_hotkey_strs(ht_context, name());
|
||||||
|
if (!hotkeys.empty())
|
||||||
|
ret += to_wx(" (" + boost::join(hotkeys, "/") + ")");
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
void reg(std::unique_ptr<Command> cmd) {
|
void reg(std::unique_ptr<Command> cmd) {
|
||||||
cmd_map[cmd->name()] = std::move(cmd);
|
cmd_map[cmd->name()] = std::move(cmd);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
/// @brief Command base class and main header.
|
/// @brief Command base class and main header.
|
||||||
/// @ingroup command
|
/// @ingroup command
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -101,6 +103,9 @@ DEFINE_EXCEPTION(CommandNotFound, CommandError);
|
||||||
/// Short help string describing what the command does
|
/// Short help string describing what the command does
|
||||||
virtual wxString StrHelp() const=0;
|
virtual wxString StrHelp() const=0;
|
||||||
|
|
||||||
|
/// Formats the Help text together with the registered hotkey
|
||||||
|
wxString GetTooltip(std::string ht_context) const;
|
||||||
|
|
||||||
/// Get this command's type flags
|
/// Get this command's type flags
|
||||||
/// @return Bitmask of CommandFlags
|
/// @return Bitmask of CommandFlags
|
||||||
virtual int Type() const { return COMMAND_NORMAL; }
|
virtual int Type() const { return COMMAND_NORMAL; }
|
||||||
|
|
|
@ -50,6 +50,24 @@ namespace {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<VisualToolVectorClipMode M>
|
||||||
|
struct visual_tool_vclip_command : public Command {
|
||||||
|
CMD_TYPE(COMMAND_VALIDATE | COMMAND_RADIO)
|
||||||
|
|
||||||
|
bool Validate(const agi::Context *c) override {
|
||||||
|
return !!c->project->VideoProvider();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsActive(const agi::Context *c) override {
|
||||||
|
return c->videoDisplay->ToolIsVectorClipTool(M);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(agi::Context *c) override {
|
||||||
|
c->videoDisplay->SetTool(agi::make_unique<VisualToolVectorClip>(c->videoDisplay, c));
|
||||||
|
c->videoDisplay->SetVectorClipTool(M);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct visual_mode_cross final : public visual_tool_command<VisualToolCross> {
|
struct visual_mode_cross final : public visual_tool_command<VisualToolCross> {
|
||||||
CMD_NAME("video/tool/cross")
|
CMD_NAME("video/tool/cross")
|
||||||
CMD_ICON(visual_standard)
|
CMD_ICON(visual_standard)
|
||||||
|
@ -105,6 +123,66 @@ namespace {
|
||||||
STR_DISP("Vector Clip")
|
STR_DISP("Vector Clip")
|
||||||
STR_HELP("Clip subtitles to a vectorial area")
|
STR_HELP("Clip subtitles to a vectorial area")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Vector clip tools
|
||||||
|
|
||||||
|
struct visual_mode_vclip_drag final : public visual_tool_vclip_command<VCLIP_DRAG> {
|
||||||
|
CMD_NAME("video/tool/vclip/drag")
|
||||||
|
CMD_ICON(visual_vector_clip_drag)
|
||||||
|
STR_MENU("Drag")
|
||||||
|
STR_DISP("Drag")
|
||||||
|
STR_HELP("Drag control points")
|
||||||
|
};
|
||||||
|
|
||||||
|
struct visual_mode_vclip_line final : public visual_tool_vclip_command<VCLIP_LINE> {
|
||||||
|
CMD_NAME("video/tool/vclip/line")
|
||||||
|
CMD_ICON(visual_vector_clip_line)
|
||||||
|
STR_MENU("Line")
|
||||||
|
STR_DISP("Line")
|
||||||
|
STR_HELP("Appends a line")
|
||||||
|
};
|
||||||
|
struct visual_mode_vclip_bicubic final : public visual_tool_vclip_command<VCLIP_BICUBIC> {
|
||||||
|
CMD_NAME("video/tool/vclip/bicubic")
|
||||||
|
CMD_ICON(visual_vector_clip_bicubic)
|
||||||
|
STR_MENU("Bicubic")
|
||||||
|
STR_DISP("Bicubic")
|
||||||
|
STR_HELP("Appends a bezier bicubic curve")
|
||||||
|
};
|
||||||
|
struct visual_mode_vclip_convert final : public visual_tool_vclip_command<VCLIP_CONVERT> {
|
||||||
|
CMD_NAME("video/tool/vclip/convert")
|
||||||
|
CMD_ICON(visual_vector_clip_convert)
|
||||||
|
STR_MENU("Convert")
|
||||||
|
STR_DISP("Convert")
|
||||||
|
STR_HELP("Converts a segment between line and bicubic")
|
||||||
|
};
|
||||||
|
struct visual_mode_vclip_insert final : public visual_tool_vclip_command<VCLIP_INSERT> {
|
||||||
|
CMD_NAME("video/tool/vclip/insert")
|
||||||
|
CMD_ICON(visual_vector_clip_insert)
|
||||||
|
STR_MENU("Insert")
|
||||||
|
STR_DISP("Insert")
|
||||||
|
STR_HELP("Inserts a control point")
|
||||||
|
};
|
||||||
|
struct visual_mode_vclip_remove final : public visual_tool_vclip_command<VCLIP_REMOVE> {
|
||||||
|
CMD_NAME("video/tool/vclip/remove")
|
||||||
|
CMD_ICON(visual_vector_clip_remove)
|
||||||
|
STR_MENU("Remove")
|
||||||
|
STR_DISP("Remove")
|
||||||
|
STR_HELP("Removes a control point")
|
||||||
|
};
|
||||||
|
struct visual_mode_vclip_freehand final : public visual_tool_vclip_command<VCLIP_FREEHAND> {
|
||||||
|
CMD_NAME("video/tool/vclip/freehand")
|
||||||
|
CMD_ICON(visual_vector_clip_freehand)
|
||||||
|
STR_MENU("Freehand")
|
||||||
|
STR_DISP("Freehand")
|
||||||
|
STR_HELP("Draws a freehand shape")
|
||||||
|
};
|
||||||
|
struct visual_mode_vclip_freehand_smooth final : public visual_tool_vclip_command<VCLIP_FREEHAND_SMOOTH> {
|
||||||
|
CMD_NAME("video/tool/vclip/freehand_smooth")
|
||||||
|
CMD_ICON(visual_vector_clip_freehand_smooth)
|
||||||
|
STR_MENU("Freehand smooth")
|
||||||
|
STR_DISP("Freehand smooth")
|
||||||
|
STR_HELP("Draws a smoothed freehand shape")
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace cmd {
|
namespace cmd {
|
||||||
|
@ -116,5 +194,14 @@ namespace cmd {
|
||||||
reg(agi::make_unique<visual_mode_scale>());
|
reg(agi::make_unique<visual_mode_scale>());
|
||||||
reg(agi::make_unique<visual_mode_clip>());
|
reg(agi::make_unique<visual_mode_clip>());
|
||||||
reg(agi::make_unique<visual_mode_vector_clip>());
|
reg(agi::make_unique<visual_mode_vector_clip>());
|
||||||
|
|
||||||
|
reg(agi::make_unique<visual_mode_vclip_drag>());
|
||||||
|
reg(agi::make_unique<visual_mode_vclip_line>());
|
||||||
|
reg(agi::make_unique<visual_mode_vclip_bicubic>());
|
||||||
|
reg(agi::make_unique<visual_mode_vclip_convert>());
|
||||||
|
reg(agi::make_unique<visual_mode_vclip_insert>());
|
||||||
|
reg(agi::make_unique<visual_mode_vclip_remove>());
|
||||||
|
reg(agi::make_unique<visual_mode_vclip_freehand>());
|
||||||
|
reg(agi::make_unique<visual_mode_vclip_freehand_smooth>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -386,9 +386,21 @@ void ColorPickerScreenDropper::DropFromScreenXY(int x, int y) {
|
||||||
wxMemoryDC capdc(capture);
|
wxMemoryDC capdc(capture);
|
||||||
capdc.SetPen(*wxTRANSPARENT_PEN);
|
capdc.SetPen(*wxTRANSPARENT_PEN);
|
||||||
#ifndef __WXMAC__
|
#ifndef __WXMAC__
|
||||||
wxScreenDC screen;
|
std::unique_ptr<wxDC> screen;
|
||||||
|
|
||||||
|
if (!OPT_GET("Tool/Color Picker/Restrict to Window")->GetBool()) {
|
||||||
|
screen = agi::make_unique<wxScreenDC>();
|
||||||
|
} else {
|
||||||
|
wxWindow *superparent = GetParent();
|
||||||
|
while (superparent->GetParent() != nullptr) {
|
||||||
|
superparent = superparent->GetParent();
|
||||||
|
}
|
||||||
|
superparent->ScreenToClient(&x, &y);
|
||||||
|
|
||||||
|
screen = agi::make_unique<wxWindowDC>(superparent);
|
||||||
|
}
|
||||||
capdc.StretchBlit(0, 0, resx * magnification, resy * magnification,
|
capdc.StretchBlit(0, 0, resx * magnification, resy * magnification,
|
||||||
&screen, x - resx / 2, y - resy / 2, resx, resy);
|
screen.get(), x - resx / 2, y - resy / 2, resx, resy);
|
||||||
#else
|
#else
|
||||||
// wxScreenDC doesn't work on recent versions of OS X so do it manually
|
// wxScreenDC doesn't work on recent versions of OS X so do it manually
|
||||||
|
|
||||||
|
|
|
@ -572,6 +572,9 @@
|
||||||
"Maximized" : false,
|
"Maximized" : false,
|
||||||
"Skip Whitespace" : true
|
"Skip Whitespace" : true
|
||||||
},
|
},
|
||||||
|
"Color Picker" : {
|
||||||
|
"Restrict to Window" : false
|
||||||
|
},
|
||||||
"Visual" : {
|
"Visual" : {
|
||||||
"Autohide": false
|
"Autohide": false
|
||||||
}
|
}
|
||||||
|
|
|
@ -572,6 +572,9 @@
|
||||||
"Maximized" : false,
|
"Maximized" : false,
|
||||||
"Skip Whitespace" : true
|
"Skip Whitespace" : true
|
||||||
},
|
},
|
||||||
|
"Color Picker" : {
|
||||||
|
"Restrict to Window" : false
|
||||||
|
},
|
||||||
"Visual" : {
|
"Visual" : {
|
||||||
"Autohide": false
|
"Autohide": false
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,6 +228,9 @@ void Interface(wxTreebook *book, Preferences *parent) {
|
||||||
auto tl_assistant = p->PageSizer(_("Translation Assistant"));
|
auto tl_assistant = p->PageSizer(_("Translation Assistant"));
|
||||||
p->OptionAdd(tl_assistant, _("Skip over whitespace"), "Tool/Translation Assistant/Skip Whitespace");
|
p->OptionAdd(tl_assistant, _("Skip over whitespace"), "Tool/Translation Assistant/Skip Whitespace");
|
||||||
|
|
||||||
|
auto color_picker = p->PageSizer(_("Color Picker"));
|
||||||
|
p->OptionAdd(color_picker, _("Restrict Screen Picker to Window"), "Tool/Color Picker/Restrict to Window");
|
||||||
|
|
||||||
p->SetSizerAndFit(p->sizer);
|
p->SetSizerAndFit(p->sizer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
/// @ingroup visual_ts
|
/// @ingroup visual_ts
|
||||||
///
|
///
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "vector2d.h"
|
#include "vector2d.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
#include <libaegisub/log.h>
|
#include <libaegisub/log.h>
|
||||||
#include <libaegisub/signal.h>
|
#include <libaegisub/signal.h>
|
||||||
|
|
||||||
#include <boost/algorithm/string/join.hpp>
|
|
||||||
#include <boost/interprocess/streams/bufferstream.hpp>
|
#include <boost/interprocess/streams/bufferstream.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -143,7 +142,7 @@ namespace {
|
||||||
wxITEM_NORMAL;
|
wxITEM_NORMAL;
|
||||||
|
|
||||||
wxBitmap const& bitmap = command->Icon(icon_size, retina_helper.GetScaleFactor(), GetLayoutDirection());
|
wxBitmap const& bitmap = command->Icon(icon_size, retina_helper.GetScaleFactor(), GetLayoutDirection());
|
||||||
AddTool(TOOL_ID_BASE + commands.size(), command->StrDisplay(context), bitmap, GetTooltip(command), kind);
|
AddTool(TOOL_ID_BASE + commands.size(), command->StrDisplay(context), bitmap, command->GetTooltip(ht_context), kind);
|
||||||
|
|
||||||
commands.push_back(command);
|
commands.push_back(command);
|
||||||
needs_onidle = needs_onidle || flags != cmd::COMMAND_NORMAL;
|
needs_onidle = needs_onidle || flags != cmd::COMMAND_NORMAL;
|
||||||
|
@ -157,16 +156,6 @@ namespace {
|
||||||
Realize();
|
Realize();
|
||||||
}
|
}
|
||||||
|
|
||||||
wxString GetTooltip(cmd::Command *command) {
|
|
||||||
wxString ret = command->StrHelp();
|
|
||||||
|
|
||||||
std::vector<std::string> hotkeys = hotkey::get_hotkey_strs(ht_context, command->name());
|
|
||||||
if (!hotkeys.empty())
|
|
||||||
ret += to_wx(" (" + boost::join(hotkeys, "/") + ")");
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Toolbar(wxWindow *parent, std::string name, agi::Context *c, std::string ht_context, bool vertical)
|
Toolbar(wxWindow *parent, std::string name, agi::Context *c, std::string ht_context, bool vertical)
|
||||||
: wxToolBar(parent, -1, wxDefaultPosition, wxDefaultSize, wxTB_NODIVIDER | wxTB_FLAT | (vertical ? wxTB_VERTICAL : wxTB_HORIZONTAL))
|
: wxToolBar(parent, -1, wxDefaultPosition, wxDefaultSize, wxTB_NODIVIDER | wxTB_FLAT | (vertical ? wxTB_VERTICAL : wxTB_HORIZONTAL))
|
||||||
|
|
|
@ -520,10 +520,23 @@ void VideoDisplay::SetTool(std::unique_ptr<VisualToolBase> new_tool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VideoDisplay::SetVectorClipTool(VisualToolVectorClipMode vcliptoolmode) const {
|
||||||
|
if (ToolIsType(typeid(VisualToolVectorClip))) {
|
||||||
|
static_cast<VisualToolVectorClip*>(tool.get())->SetMode(vcliptoolmode);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool VideoDisplay::ToolIsType(std::type_info const& type) const {
|
bool VideoDisplay::ToolIsType(std::type_info const& type) const {
|
||||||
return tool && typeid(*tool) == type;
|
return tool && typeid(*tool) == type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool VideoDisplay::ToolIsVectorClipTool(VisualToolVectorClipMode vcliptoolmode) const {
|
||||||
|
return ToolIsType(typeid(VisualToolVectorClip)) && static_cast<VisualToolVectorClip*>(tool.get());
|
||||||
|
}
|
||||||
|
|
||||||
Vector2D VideoDisplay::GetMousePosition() const {
|
Vector2D VideoDisplay::GetMousePosition() const {
|
||||||
return last_mouse_pos ? tool->ToScriptCoords(last_mouse_pos) : last_mouse_pos;
|
return last_mouse_pos ? tool->ToScriptCoords(last_mouse_pos) : last_mouse_pos;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include <libaegisub/signal.h>
|
#include <libaegisub/signal.h>
|
||||||
|
|
||||||
#include "vector2d.h"
|
#include "vector2d.h"
|
||||||
|
#include "visual_tool_vector_clip.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <typeinfo>
|
#include <typeinfo>
|
||||||
|
@ -180,8 +181,14 @@ public:
|
||||||
|
|
||||||
void SetTool(std::unique_ptr<VisualToolBase> new_tool);
|
void SetTool(std::unique_ptr<VisualToolBase> new_tool);
|
||||||
|
|
||||||
|
/// Will only set the vector clip mode if the vector clip tool is active already,
|
||||||
|
/// otherwise it just returns false.
|
||||||
|
bool SetVectorClipTool(VisualToolVectorClipMode vcliptoolmode) const;
|
||||||
|
|
||||||
bool ToolIsType(std::type_info const& type) const;
|
bool ToolIsType(std::type_info const& type) const;
|
||||||
|
|
||||||
|
bool ToolIsVectorClipTool(VisualToolVectorClipMode vcliptoolmode) const;
|
||||||
|
|
||||||
/// Discard all OpenGL state
|
/// Discard all OpenGL state
|
||||||
void Unload();
|
void Unload();
|
||||||
};
|
};
|
||||||
|
|
|
@ -30,18 +30,7 @@
|
||||||
#include <boost/range/algorithm/set_algorithm.hpp>
|
#include <boost/range/algorithm/set_algorithm.hpp>
|
||||||
#include <wx/toolbar.h>
|
#include <wx/toolbar.h>
|
||||||
|
|
||||||
/// Button IDs
|
int BUTTON_ID_BASE = 1300;
|
||||||
enum {
|
|
||||||
BUTTON_DRAG = 1300,
|
|
||||||
BUTTON_LINE,
|
|
||||||
BUTTON_BICUBIC,
|
|
||||||
BUTTON_CONVERT,
|
|
||||||
BUTTON_INSERT,
|
|
||||||
BUTTON_REMOVE,
|
|
||||||
BUTTON_FREEHAND,
|
|
||||||
BUTTON_FREEHAND_SMOOTH,
|
|
||||||
BUTTON_LAST // Leave this at the end and don't use it
|
|
||||||
};
|
|
||||||
|
|
||||||
VisualToolVectorClip::VisualToolVectorClip(VideoDisplay *parent, agi::Context *context)
|
VisualToolVectorClip::VisualToolVectorClip(VideoDisplay *parent, agi::Context *context)
|
||||||
: VisualTool<VisualToolVectorClipDraggableFeature>(parent, context)
|
: VisualTool<VisualToolVectorClipDraggableFeature>(parent, context)
|
||||||
|
@ -49,41 +38,64 @@ VisualToolVectorClip::VisualToolVectorClip(VideoDisplay *parent, agi::Context *c
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Having the mode as an extra argument here isn't the cleanest, but using a counter instead
|
||||||
|
// as is done in toolbar.cpp feels like too big of a hack. At least this way the button's actions
|
||||||
|
// are not purely controlled by the order they're added in.
|
||||||
|
void VisualToolVectorClip::AddTool(std::string command_name, VisualToolVectorClipMode mode) {
|
||||||
|
cmd::Command *command;
|
||||||
|
try {
|
||||||
|
command = cmd::get(command_name);
|
||||||
|
}
|
||||||
|
catch (cmd::CommandNotFound const&) {
|
||||||
|
// Toolbar names are all hardcoded so this should never happen
|
||||||
|
throw agi::InternalError("Toolbar named " + command_name + " not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
int icon_size = OPT_GET("App/Toolbar Icon Size")->GetInt();
|
||||||
|
toolBar->AddTool(BUTTON_ID_BASE + mode, command->StrDisplay(c), command->Icon(icon_size), command->GetTooltip("Video"), wxITEM_CHECK);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void VisualToolVectorClip::SetToolbar(wxToolBar *toolBar) {
|
void VisualToolVectorClip::SetToolbar(wxToolBar *toolBar) {
|
||||||
this->toolBar = toolBar;
|
this->toolBar = toolBar;
|
||||||
|
|
||||||
toolBar->AddSeparator();
|
toolBar->AddSeparator();
|
||||||
|
|
||||||
int icon_size = OPT_GET("App/Toolbar Icon Size")->GetInt();
|
AddTool("video/tool/vclip/drag", VCLIP_DRAG);
|
||||||
|
AddTool("video/tool/vclip/line", VCLIP_LINE);
|
||||||
|
AddTool("video/tool/vclip/bicubic", VCLIP_BICUBIC);
|
||||||
|
toolBar->AddSeparator();
|
||||||
|
AddTool("video/tool/vclip/convert", VCLIP_CONVERT);
|
||||||
|
AddTool("video/tool/vclip/insert", VCLIP_INSERT);
|
||||||
|
AddTool("video/tool/vclip/remove", VCLIP_REMOVE);
|
||||||
|
toolBar->AddSeparator();
|
||||||
|
AddTool("video/tool/vclip/freehand", VCLIP_FREEHAND);
|
||||||
|
AddTool("video/tool/vclip/freehand_smooth", VCLIP_FREEHAND_SMOOTH);
|
||||||
|
|
||||||
#define ICON(name) icon_size == 16 ? GETIMAGE(name ## _16) : GETIMAGE(name ## _24)
|
toolBar->ToggleTool(BUTTON_ID_BASE + VCLIP_DRAG, true);
|
||||||
toolBar->AddTool(BUTTON_DRAG, _("Drag"), ICON(visual_vector_clip_drag), _("Drag control points"), wxITEM_CHECK);
|
|
||||||
toolBar->AddTool(BUTTON_LINE, _("Line"), ICON(visual_vector_clip_line), _("Appends a line"), wxITEM_CHECK);
|
|
||||||
toolBar->AddTool(BUTTON_BICUBIC, _("Bicubic"), ICON(visual_vector_clip_bicubic), _("Appends a bezier bicubic curve"), wxITEM_CHECK);
|
|
||||||
toolBar->AddSeparator();
|
|
||||||
toolBar->AddTool(BUTTON_CONVERT, _("Convert"), ICON(visual_vector_clip_convert), _("Converts a segment between line and bicubic"), wxITEM_CHECK);
|
|
||||||
toolBar->AddTool(BUTTON_INSERT, _("Insert"), ICON(visual_vector_clip_insert), _("Inserts a control point"), wxITEM_CHECK);
|
|
||||||
toolBar->AddTool(BUTTON_REMOVE, _("Remove"), ICON(visual_vector_clip_remove), _("Removes a control point"), wxITEM_CHECK);
|
|
||||||
toolBar->AddSeparator();
|
|
||||||
toolBar->AddTool(BUTTON_FREEHAND, _("Freehand"), ICON(visual_vector_clip_freehand), _("Draws a freehand shape"), wxITEM_CHECK);
|
|
||||||
toolBar->AddTool(BUTTON_FREEHAND_SMOOTH, _("Freehand smooth"), ICON(visual_vector_clip_freehand_smooth), _("Draws a smoothed freehand shape"), wxITEM_CHECK);
|
|
||||||
toolBar->ToggleTool(BUTTON_DRAG, true);
|
|
||||||
toolBar->Realize();
|
toolBar->Realize();
|
||||||
toolBar->Show(true);
|
toolBar->Show(true);
|
||||||
toolBar->Bind(wxEVT_TOOL, [=](wxCommandEvent& e) { SetMode(e.GetId() - BUTTON_DRAG); });
|
toolBar->Bind(wxEVT_TOOL, [=](wxCommandEvent& e) { SetMode((VisualToolVectorClipMode) (e.GetId() - BUTTON_ID_BASE)); });
|
||||||
SetMode(features.empty());
|
SetMode(VCLIP_DRAG);
|
||||||
#undef ICON
|
#undef ICON
|
||||||
}
|
}
|
||||||
|
|
||||||
void VisualToolVectorClip::SetMode(int new_mode) {
|
void VisualToolVectorClip::SetMode(VisualToolVectorClipMode new_mode) {
|
||||||
|
if (toolBar == nullptr) {
|
||||||
|
throw agi::InternalError("Vector clip toolbar hasn't been set yet!");
|
||||||
|
}
|
||||||
// Manually enforce radio behavior as we want one selection in the bar
|
// Manually enforce radio behavior as we want one selection in the bar
|
||||||
// rather than one per group
|
// rather than one per group
|
||||||
for (int i = BUTTON_DRAG; i < BUTTON_LAST; i++)
|
for (int i = 0; i < VCLIP_LAST; i++)
|
||||||
toolBar->ToggleTool(i, i == new_mode + BUTTON_DRAG);
|
toolBar->ToggleTool(BUTTON_ID_BASE + i, i == new_mode);
|
||||||
|
|
||||||
mode = new_mode;
|
mode = new_mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VisualToolVectorClipMode VisualToolVectorClip::GetMode() {
|
||||||
|
return mode;
|
||||||
|
}
|
||||||
|
|
||||||
void VisualToolVectorClip::Draw() {
|
void VisualToolVectorClip::Draw() {
|
||||||
if (!active_line) return;
|
if (!active_line) return;
|
||||||
if (spline.empty()) return;
|
if (spline.empty()) return;
|
||||||
|
@ -107,7 +119,7 @@ void VisualToolVectorClip::Draw() {
|
||||||
// draw the shade over clipped out areas and line showing the clip
|
// draw the shade over clipped out areas and line showing the clip
|
||||||
gl.DrawMultiPolygon(points, start, count, video_pos, video_res, !inverse);
|
gl.DrawMultiPolygon(points, start, count, video_pos, video_res, !inverse);
|
||||||
|
|
||||||
if (mode == 0 && holding && drag_start && mouse_pos) {
|
if (mode == VCLIP_DRAG && holding && drag_start && mouse_pos) {
|
||||||
// Draw drag-select box
|
// Draw drag-select box
|
||||||
Vector2D top_left = drag_start.Min(mouse_pos);
|
Vector2D top_left = drag_start.Min(mouse_pos);
|
||||||
Vector2D bottom_right = drag_start.Max(mouse_pos);
|
Vector2D bottom_right = drag_start.Max(mouse_pos);
|
||||||
|
@ -123,7 +135,7 @@ void VisualToolVectorClip::Draw() {
|
||||||
spline.GetClosestParametricPoint(mouse_pos, highlighted_curve, t, pt);
|
spline.GetClosestParametricPoint(mouse_pos, highlighted_curve, t, pt);
|
||||||
|
|
||||||
// Draw highlighted line
|
// Draw highlighted line
|
||||||
if ((mode == 3 || mode == 4) && !active_feature && points.size() > 2) {
|
if ((mode == VCLIP_CONVERT || mode == VCLIP_INSERT) && !active_feature && points.size() > 2) {
|
||||||
auto highlighted_points = spline.GetPointList(highlighted_curve);
|
auto highlighted_points = spline.GetPointList(highlighted_curve);
|
||||||
if (!highlighted_points.empty()) {
|
if (!highlighted_points.empty()) {
|
||||||
gl.SetLineColour(highlight_color_secondary, 1.f, 2);
|
gl.SetLineColour(highlight_color_secondary, 1.f, 2);
|
||||||
|
@ -160,7 +172,7 @@ void VisualToolVectorClip::Draw() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw preview of inserted line
|
// Draw preview of inserted line
|
||||||
if (mode == 1 || mode == 2) {
|
if (mode == VCLIP_LINE || mode == VCLIP_BICUBIC) {
|
||||||
if (spline.size() && mouse_pos) {
|
if (spline.size() && mouse_pos) {
|
||||||
auto c0 = std::find_if(spline.rbegin(), spline.rend(),
|
auto c0 = std::find_if(spline.rbegin(), spline.rend(),
|
||||||
[](SplineCurve const& s) { return s.type == SplineCurve::POINT; });
|
[](SplineCurve const& s) { return s.type == SplineCurve::POINT; });
|
||||||
|
@ -171,7 +183,7 @@ void VisualToolVectorClip::Draw() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Draw preview of insert point
|
// Draw preview of insert point
|
||||||
if (mode == 4)
|
if (mode == VCLIP_INSERT)
|
||||||
gl.DrawCircle(pt, 4);
|
gl.DrawCircle(pt, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,13 +290,13 @@ bool VisualToolVectorClip::InitializeDrag(Feature *feature) {
|
||||||
|
|
||||||
bool VisualToolVectorClip::InitializeHold() {
|
bool VisualToolVectorClip::InitializeHold() {
|
||||||
// Box selection
|
// Box selection
|
||||||
if (mode == 0) {
|
if (mode == VCLIP_DRAG) {
|
||||||
box_added.clear();
|
box_added.clear();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert line/bicubic
|
// Insert line/bicubic
|
||||||
if (mode == 1 || mode == 2) {
|
if (mode == VCLIP_LINE || mode == VCLIP_BICUBIC) {
|
||||||
SplineCurve curve;
|
SplineCurve curve;
|
||||||
|
|
||||||
// New spline beginning at the clicked point
|
// New spline beginning at the clicked point
|
||||||
|
@ -296,7 +308,7 @@ bool VisualToolVectorClip::InitializeHold() {
|
||||||
// Continue from the spline in progress
|
// Continue from the spline in progress
|
||||||
// Don't bother setting p2 as UpdateHold will handle that
|
// Don't bother setting p2 as UpdateHold will handle that
|
||||||
curve.p1 = spline.back().EndPoint();
|
curve.p1 = spline.back().EndPoint();
|
||||||
curve.type = mode == 1 ? SplineCurve::LINE : SplineCurve::BICUBIC;
|
curve.type = mode == VCLIP_LINE ? SplineCurve::LINE : SplineCurve::BICUBIC;
|
||||||
}
|
}
|
||||||
|
|
||||||
spline.push_back(curve);
|
spline.push_back(curve);
|
||||||
|
@ -307,7 +319,7 @@ bool VisualToolVectorClip::InitializeHold() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert and insert
|
// Convert and insert
|
||||||
if (mode == 3 || mode == 4) {
|
if (mode == VCLIP_CONVERT || mode == VCLIP_INSERT) {
|
||||||
// Get closest point
|
// Get closest point
|
||||||
Vector2D pt;
|
Vector2D pt;
|
||||||
Spline::iterator curve;
|
Spline::iterator curve;
|
||||||
|
@ -315,7 +327,7 @@ bool VisualToolVectorClip::InitializeHold() {
|
||||||
spline.GetClosestParametricPoint(mouse_pos, curve, t, pt);
|
spline.GetClosestParametricPoint(mouse_pos, curve, t, pt);
|
||||||
|
|
||||||
// Convert line <-> bicubic
|
// Convert line <-> bicubic
|
||||||
if (mode == 3) {
|
if (mode == VCLIP_CONVERT) {
|
||||||
if (curve != spline.end()) {
|
if (curve != spline.end()) {
|
||||||
if (curve->type == SplineCurve::LINE) {
|
if (curve->type == SplineCurve::LINE) {
|
||||||
curve->type = SplineCurve::BICUBIC;
|
curve->type = SplineCurve::BICUBIC;
|
||||||
|
@ -353,7 +365,7 @@ bool VisualToolVectorClip::InitializeHold() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Freehand spline draw
|
// Freehand spline draw
|
||||||
if (mode == 6 || mode == 7) {
|
if (mode == VCLIP_FREEHAND || mode == VCLIP_FREEHAND_SMOOTH) {
|
||||||
sel_features.clear();
|
sel_features.clear();
|
||||||
features.clear();
|
features.clear();
|
||||||
active_feature = nullptr;
|
active_feature = nullptr;
|
||||||
|
@ -375,7 +387,7 @@ static bool in_box(Vector2D top_left, Vector2D bottom_right, Vector2D p) {
|
||||||
|
|
||||||
void VisualToolVectorClip::UpdateHold() {
|
void VisualToolVectorClip::UpdateHold() {
|
||||||
// Box selection
|
// Box selection
|
||||||
if (mode == 0) {
|
if (mode == VCLIP_DRAG) {
|
||||||
std::set<Feature *> boxed_features;
|
std::set<Feature *> boxed_features;
|
||||||
Vector2D p1 = drag_start.Min(mouse_pos);
|
Vector2D p1 = drag_start.Min(mouse_pos);
|
||||||
Vector2D p2 = drag_start.Max(mouse_pos);
|
Vector2D p2 = drag_start.Max(mouse_pos);
|
||||||
|
@ -399,13 +411,13 @@ void VisualToolVectorClip::UpdateHold() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == 1) {
|
if (mode == VCLIP_LINE) {
|
||||||
spline.back().EndPoint() = mouse_pos;
|
spline.back().EndPoint() = mouse_pos;
|
||||||
features.back().pos = mouse_pos;
|
features.back().pos = mouse_pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert bicubic
|
// Insert bicubic
|
||||||
else if (mode == 2) {
|
else if (mode == VCLIP_BICUBIC) {
|
||||||
SplineCurve &curve = spline.back();
|
SplineCurve &curve = spline.back();
|
||||||
curve.EndPoint() = mouse_pos;
|
curve.EndPoint() = mouse_pos;
|
||||||
|
|
||||||
|
@ -422,25 +434,25 @@ void VisualToolVectorClip::UpdateHold() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Freehand
|
// Freehand
|
||||||
else if (mode == 6 || mode == 7) {
|
else if (mode == VCLIP_FREEHAND || mode == VCLIP_FREEHAND_SMOOTH) {
|
||||||
// See if distance is enough
|
// See if distance is enough
|
||||||
Vector2D const& last = spline.back().EndPoint();
|
Vector2D const& last = spline.back().EndPoint();
|
||||||
float len = (last - mouse_pos).SquareLen();
|
float len = (last - mouse_pos).SquareLen();
|
||||||
if ((mode == 6 && len >= 900) || (mode == 7 && len >= 3600)) {
|
if ((mode == VCLIP_FREEHAND && len >= 900) || (mode == VCLIP_FREEHAND_SMOOTH && len >= 3600)) {
|
||||||
spline.emplace_back(last, mouse_pos);
|
spline.emplace_back(last, mouse_pos);
|
||||||
MakeFeature(spline.size() - 1);
|
MakeFeature(spline.size() - 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode == 3 || mode == 4) return;
|
if (mode == VCLIP_CONVERT || mode == VCLIP_INSERT) return;
|
||||||
|
|
||||||
// Smooth spline
|
// Smooth spline
|
||||||
if (!holding && mode == 7)
|
if (!holding && mode == VCLIP_FREEHAND_SMOOTH)
|
||||||
spline.Smooth();
|
spline.Smooth();
|
||||||
|
|
||||||
// End freedraw
|
// End freedraw
|
||||||
if (!holding && (mode == 6 || mode == 7)) {
|
if (!holding && (mode == VCLIP_FREEHAND || mode == VCLIP_FREEHAND_SMOOTH)) {
|
||||||
SetMode(0);
|
SetMode(VCLIP_DRAG);
|
||||||
MakeFeatures();
|
MakeFeatures();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,12 +14,28 @@
|
||||||
//
|
//
|
||||||
// Aegisub Project http://www.aegisub.org/
|
// Aegisub Project http://www.aegisub.org/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
#include "visual_feature.h"
|
#include "visual_feature.h"
|
||||||
#include "visual_tool.h"
|
#include "visual_tool.h"
|
||||||
#include "spline.h"
|
#include "spline.h"
|
||||||
|
#include "command/command.h"
|
||||||
|
|
||||||
class wxToolBar;
|
class wxToolBar;
|
||||||
|
|
||||||
|
/// Button IDs
|
||||||
|
enum VisualToolVectorClipMode {
|
||||||
|
VCLIP_DRAG = 0, // Assumed to be at the start
|
||||||
|
VCLIP_LINE,
|
||||||
|
VCLIP_BICUBIC,
|
||||||
|
VCLIP_CONVERT,
|
||||||
|
VCLIP_INSERT,
|
||||||
|
VCLIP_REMOVE,
|
||||||
|
VCLIP_FREEHAND,
|
||||||
|
VCLIP_FREEHAND_SMOOTH,
|
||||||
|
VCLIP_LAST // Leave this at the end and don't use it
|
||||||
|
};
|
||||||
|
|
||||||
/// @class VisualToolVectorClipDraggableFeature
|
/// @class VisualToolVectorClipDraggableFeature
|
||||||
/// @brief VisualDraggableFeature with information about a feature's location
|
/// @brief VisualDraggableFeature with information about a feature's location
|
||||||
/// in the spline
|
/// in the spline
|
||||||
|
@ -33,18 +49,16 @@ struct VisualToolVectorClipDraggableFeature final : public VisualDraggableFeatur
|
||||||
class VisualToolVectorClip final : public VisualTool<VisualToolVectorClipDraggableFeature> {
|
class VisualToolVectorClip final : public VisualTool<VisualToolVectorClipDraggableFeature> {
|
||||||
Spline spline; /// The current spline
|
Spline spline; /// The current spline
|
||||||
wxToolBar *toolBar = nullptr; /// The subtoolbar
|
wxToolBar *toolBar = nullptr; /// The subtoolbar
|
||||||
int mode = 0; /// 0-7
|
VisualToolVectorClipMode mode = VCLIP_DRAG; /// 0-7
|
||||||
bool inverse = false; /// is iclip?
|
bool inverse = false; /// is iclip?
|
||||||
|
|
||||||
std::set<Feature *> box_added;
|
std::set<Feature *> box_added;
|
||||||
|
|
||||||
/// @brief Set the mode
|
|
||||||
/// @param mode 0-7
|
|
||||||
void SetMode(int mode);
|
|
||||||
|
|
||||||
void Save();
|
void Save();
|
||||||
void Commit(wxString message="") override;
|
void Commit(wxString message="") override;
|
||||||
|
|
||||||
|
void AddTool(std::string command_name, VisualToolVectorClipMode mode);
|
||||||
|
|
||||||
void MakeFeature(size_t idx);
|
void MakeFeature(size_t idx);
|
||||||
void MakeFeatures();
|
void MakeFeatures();
|
||||||
|
|
||||||
|
@ -60,4 +74,10 @@ class VisualToolVectorClip final : public VisualTool<VisualToolVectorClipDraggab
|
||||||
public:
|
public:
|
||||||
VisualToolVectorClip(VideoDisplay *parent, agi::Context *context);
|
VisualToolVectorClip(VideoDisplay *parent, agi::Context *context);
|
||||||
void SetToolbar(wxToolBar *tb) override;
|
void SetToolbar(wxToolBar *tb) override;
|
||||||
|
|
||||||
|
/// @brief Set the mode. Only valid if the tool is already active.
|
||||||
|
/// @param mode
|
||||||
|
void SetMode(VisualToolVectorClipMode mode);
|
||||||
|
|
||||||
|
VisualToolVectorClipMode GetMode();
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue