From 77af0c40dc73f895b082f9ec2e6d80463122783c Mon Sep 17 00:00:00 2001 From: arch1t3cht Date: Tue, 12 Jul 2022 00:58:14 +0200 Subject: [PATCH 1/7] Use public enum for visual clip tool modes --- src/visual_tool_vector_clip.cpp | 79 ++++++++++++++------------------- src/visual_tool_vector_clip.h | 17 ++++++- 2 files changed, 49 insertions(+), 47 deletions(-) diff --git a/src/visual_tool_vector_clip.cpp b/src/visual_tool_vector_clip.cpp index 701937798..25bffe4cb 100644 --- a/src/visual_tool_vector_clip.cpp +++ b/src/visual_tool_vector_clip.cpp @@ -30,18 +30,7 @@ #include #include -/// Button IDs -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 -}; +int BUTTON_ID_BASE = 1300; VisualToolVectorClip::VisualToolVectorClip(VideoDisplay *parent, agi::Context *context) : VisualTool(parent, context) @@ -57,29 +46,29 @@ void VisualToolVectorClip::SetToolbar(wxToolBar *toolBar) { int icon_size = OPT_GET("App/Toolbar Icon Size")->GetInt(); #define ICON(name) icon_size == 16 ? GETIMAGE(name ## _16) : GETIMAGE(name ## _24) - 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->AddTool(BUTTON_ID_BASE + VCLIP_DRAG, _("Drag"), ICON(visual_vector_clip_drag), _("Drag control points"), wxITEM_CHECK); + toolBar->AddTool(BUTTON_ID_BASE + VCLIP_LINE, _("Line"), ICON(visual_vector_clip_line), _("Appends a line"), wxITEM_CHECK); + toolBar->AddTool(BUTTON_ID_BASE + VCLIP_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->AddTool(BUTTON_ID_BASE + VCLIP_CONVERT, _("Convert"), ICON(visual_vector_clip_convert), _("Converts a segment between line and bicubic"), wxITEM_CHECK); + toolBar->AddTool(BUTTON_ID_BASE + VCLIP_INSERT, _("Insert"), ICON(visual_vector_clip_insert), _("Inserts a control point"), wxITEM_CHECK); + toolBar->AddTool(BUTTON_ID_BASE + VCLIP_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->AddTool(BUTTON_ID_BASE + VCLIP_FREEHAND, _("Freehand"), ICON(visual_vector_clip_freehand), _("Draws a freehand shape"), wxITEM_CHECK); + toolBar->AddTool(BUTTON_ID_BASE + VCLIP_FREEHAND_SMOOTH, _("Freehand smooth"), ICON(visual_vector_clip_freehand_smooth), _("Draws a smoothed freehand shape"), wxITEM_CHECK); + toolBar->ToggleTool(BUTTON_ID_BASE + VCLIP_DRAG, true); toolBar->Realize(); toolBar->Show(true); - toolBar->Bind(wxEVT_TOOL, [=](wxCommandEvent& e) { SetMode(e.GetId() - BUTTON_DRAG); }); - SetMode(features.empty()); + toolBar->Bind(wxEVT_TOOL, [=](wxCommandEvent& e) { SetMode((VisualToolVectorClipMode) (e.GetId() - BUTTON_ID_BASE)); }); + SetMode(VCLIP_DRAG); #undef ICON } -void VisualToolVectorClip::SetMode(int new_mode) { +void VisualToolVectorClip::SetMode(VisualToolVectorClipMode new_mode) { // Manually enforce radio behavior as we want one selection in the bar // rather than one per group - for (int i = BUTTON_DRAG; i < BUTTON_LAST; i++) - toolBar->ToggleTool(i, i == new_mode + BUTTON_DRAG); + for (int i = 0; i < VCLIP_LAST; i++) + toolBar->ToggleTool(BUTTON_ID_BASE + i, i == new_mode); mode = new_mode; } @@ -107,7 +96,7 @@ void VisualToolVectorClip::Draw() { // draw the shade over clipped out areas and line showing the clip 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 Vector2D top_left = drag_start.Min(mouse_pos); Vector2D bottom_right = drag_start.Max(mouse_pos); @@ -123,7 +112,7 @@ void VisualToolVectorClip::Draw() { spline.GetClosestParametricPoint(mouse_pos, highlighted_curve, t, pt); // 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); if (!highlighted_points.empty()) { gl.SetLineColour(highlight_color_secondary, 1.f, 2); @@ -160,7 +149,7 @@ void VisualToolVectorClip::Draw() { } // Draw preview of inserted line - if (mode == 1 || mode == 2) { + if (mode == VCLIP_LINE || mode == VCLIP_BICUBIC) { if (spline.size() && mouse_pos) { auto c0 = std::find_if(spline.rbegin(), spline.rend(), [](SplineCurve const& s) { return s.type == SplineCurve::POINT; }); @@ -171,7 +160,7 @@ void VisualToolVectorClip::Draw() { } // Draw preview of insert point - if (mode == 4) + if (mode == VCLIP_INSERT) gl.DrawCircle(pt, 4); } @@ -278,13 +267,13 @@ bool VisualToolVectorClip::InitializeDrag(Feature *feature) { bool VisualToolVectorClip::InitializeHold() { // Box selection - if (mode == 0) { + if (mode == VCLIP_DRAG) { box_added.clear(); return true; } // Insert line/bicubic - if (mode == 1 || mode == 2) { + if (mode == VCLIP_LINE || mode == VCLIP_BICUBIC) { SplineCurve curve; // New spline beginning at the clicked point @@ -296,7 +285,7 @@ bool VisualToolVectorClip::InitializeHold() { // Continue from the spline in progress // Don't bother setting p2 as UpdateHold will handle that curve.p1 = spline.back().EndPoint(); - curve.type = mode == 1 ? SplineCurve::LINE : SplineCurve::BICUBIC; + curve.type = mode == VCLIP_LINE ? SplineCurve::LINE : SplineCurve::BICUBIC; } spline.push_back(curve); @@ -307,7 +296,7 @@ bool VisualToolVectorClip::InitializeHold() { } // Convert and insert - if (mode == 3 || mode == 4) { + if (mode == VCLIP_CONVERT || mode == VCLIP_INSERT) { // Get closest point Vector2D pt; Spline::iterator curve; @@ -315,7 +304,7 @@ bool VisualToolVectorClip::InitializeHold() { spline.GetClosestParametricPoint(mouse_pos, curve, t, pt); // Convert line <-> bicubic - if (mode == 3) { + if (mode == VCLIP_CONVERT) { if (curve != spline.end()) { if (curve->type == SplineCurve::LINE) { curve->type = SplineCurve::BICUBIC; @@ -353,7 +342,7 @@ bool VisualToolVectorClip::InitializeHold() { } // Freehand spline draw - if (mode == 6 || mode == 7) { + if (mode == VCLIP_FREEHAND || mode == VCLIP_FREEHAND_SMOOTH) { sel_features.clear(); features.clear(); active_feature = nullptr; @@ -375,7 +364,7 @@ static bool in_box(Vector2D top_left, Vector2D bottom_right, Vector2D p) { void VisualToolVectorClip::UpdateHold() { // Box selection - if (mode == 0) { + if (mode == VCLIP_DRAG) { std::set boxed_features; Vector2D p1 = drag_start.Min(mouse_pos); Vector2D p2 = drag_start.Max(mouse_pos); @@ -399,13 +388,13 @@ void VisualToolVectorClip::UpdateHold() { return; } - if (mode == 1) { + if (mode == VCLIP_LINE) { spline.back().EndPoint() = mouse_pos; features.back().pos = mouse_pos; } // Insert bicubic - else if (mode == 2) { + else if (mode == VCLIP_BICUBIC) { SplineCurve &curve = spline.back(); curve.EndPoint() = mouse_pos; @@ -422,25 +411,25 @@ void VisualToolVectorClip::UpdateHold() { } // Freehand - else if (mode == 6 || mode == 7) { + else if (mode == VCLIP_FREEHAND || mode == VCLIP_FREEHAND_SMOOTH) { // See if distance is enough Vector2D const& last = spline.back().EndPoint(); 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); MakeFeature(spline.size() - 1); } } - if (mode == 3 || mode == 4) return; + if (mode == VCLIP_CONVERT || mode == VCLIP_INSERT) return; // Smooth spline - if (!holding && mode == 7) + if (!holding && mode == VCLIP_FREEHAND_SMOOTH) spline.Smooth(); // End freedraw - if (!holding && (mode == 6 || mode == 7)) { - SetMode(0); + if (!holding && (mode == VCLIP_FREEHAND || mode == VCLIP_FREEHAND_SMOOTH)) { + SetMode(VCLIP_DRAG); MakeFeatures(); } } diff --git a/src/visual_tool_vector_clip.h b/src/visual_tool_vector_clip.h index ae88213a6..b9d2fdc14 100644 --- a/src/visual_tool_vector_clip.h +++ b/src/visual_tool_vector_clip.h @@ -20,6 +20,19 @@ 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 /// @brief VisualDraggableFeature with information about a feature's location /// in the spline @@ -33,14 +46,14 @@ struct VisualToolVectorClipDraggableFeature final : public VisualDraggableFeatur class VisualToolVectorClip final : public VisualTool { Spline spline; /// The current spline wxToolBar *toolBar = nullptr; /// The subtoolbar - int mode = 0; /// 0-7 + VisualToolVectorClipMode mode = VCLIP_DRAG; /// 0-7 bool inverse = false; /// is iclip? std::set box_added; /// @brief Set the mode /// @param mode 0-7 - void SetMode(int mode); + void SetMode(VisualToolVectorClipMode mode); void Save(); void Commit(wxString message="") override; From 10d233d3e29ca4fc34f90ea046c1eeaee9d3051c Mon Sep 17 00:00:00 2001 From: arch1t3cht Date: Tue, 12 Jul 2022 14:14:44 +0200 Subject: [PATCH 2/7] Add bindable commands for visual vector clip tools --- src/command/vis_tool.cpp | 88 +++++++++++++++++++++++++++++++++ src/spline_curve.h | 2 + src/video_display.cpp | 13 +++++ src/video_display.h | 7 +++ src/visual_tool_vector_clip.cpp | 7 +++ src/visual_tool_vector_clip.h | 12 +++-- 6 files changed, 125 insertions(+), 4 deletions(-) diff --git a/src/command/vis_tool.cpp b/src/command/vis_tool.cpp index 168f427ee..c898d87f3 100644 --- a/src/command/vis_tool.cpp +++ b/src/command/vis_tool.cpp @@ -50,6 +50,25 @@ namespace { } }; + template + 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 { + std::unique_ptr vclip = agi::make_unique(c->videoDisplay, c); + c->videoDisplay->SetTool(std::move(vclip)); + c->videoDisplay->SetVectorClipTool(M); + } + }; + struct visual_mode_cross final : public visual_tool_command { CMD_NAME("video/tool/cross") CMD_ICON(visual_standard) @@ -105,6 +124,66 @@ namespace { STR_DISP("Vector Clip") STR_HELP("Clip subtitles to a vectorial area") }; + + // Vector clip tools + + struct visual_mode_vclip_drag final : public visual_tool_vclip_command { + 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 { + 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 { + 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 { + 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 { + 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 { + 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 { + 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 { + 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 { @@ -116,5 +195,14 @@ namespace cmd { reg(agi::make_unique()); reg(agi::make_unique()); reg(agi::make_unique()); + + reg(agi::make_unique()); + reg(agi::make_unique()); + reg(agi::make_unique()); + reg(agi::make_unique()); + reg(agi::make_unique()); + reg(agi::make_unique()); + reg(agi::make_unique()); + reg(agi::make_unique()); } } diff --git a/src/spline_curve.h b/src/spline_curve.h index c6c3c0b35..4630a64d2 100644 --- a/src/spline_curve.h +++ b/src/spline_curve.h @@ -32,6 +32,8 @@ /// @ingroup visual_ts /// +#pragma once + #include "vector2d.h" #include diff --git a/src/video_display.cpp b/src/video_display.cpp index 8d85311a6..8669b366b 100644 --- a/src/video_display.cpp +++ b/src/video_display.cpp @@ -428,10 +428,23 @@ void VideoDisplay::SetTool(std::unique_ptr new_tool) { } } +bool VideoDisplay::SetVectorClipTool(VisualToolVectorClipMode vcliptoolmode) const { + if (ToolIsType(typeid(VisualToolVectorClip))) { + static_cast(tool.get())->SetMode(vcliptoolmode); + return true; + } else { + return false; + } +} + bool VideoDisplay::ToolIsType(std::type_info const& type) const { return tool && typeid(*tool) == type; } +bool VideoDisplay::ToolIsVectorClipTool(VisualToolVectorClipMode vcliptoolmode) const { + return ToolIsType(typeid(VisualToolVectorClip)) && static_cast(tool.get()); +} + Vector2D VideoDisplay::GetMousePosition() const { return last_mouse_pos ? tool->ToScriptCoords(last_mouse_pos) : last_mouse_pos; } diff --git a/src/video_display.h b/src/video_display.h index f0d65edb6..799dc2441 100644 --- a/src/video_display.h +++ b/src/video_display.h @@ -35,6 +35,7 @@ #include #include "vector2d.h" +#include "visual_tool_vector_clip.h" #include #include @@ -165,8 +166,14 @@ public: void SetTool(std::unique_ptr 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 ToolIsVectorClipTool(VisualToolVectorClipMode vcliptoolmode) const; + /// Discard all OpenGL state void Unload(); }; diff --git a/src/visual_tool_vector_clip.cpp b/src/visual_tool_vector_clip.cpp index 25bffe4cb..8cae6b513 100644 --- a/src/visual_tool_vector_clip.cpp +++ b/src/visual_tool_vector_clip.cpp @@ -65,6 +65,9 @@ void VisualToolVectorClip::SetToolbar(wxToolBar *toolBar) { } 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 // rather than one per group for (int i = 0; i < VCLIP_LAST; i++) @@ -73,6 +76,10 @@ void VisualToolVectorClip::SetMode(VisualToolVectorClipMode new_mode) { mode = new_mode; } +VisualToolVectorClipMode VisualToolVectorClip::GetMode() { + return mode; +} + void VisualToolVectorClip::Draw() { if (!active_line) return; if (spline.empty()) return; diff --git a/src/visual_tool_vector_clip.h b/src/visual_tool_vector_clip.h index b9d2fdc14..4f0c8d0be 100644 --- a/src/visual_tool_vector_clip.h +++ b/src/visual_tool_vector_clip.h @@ -14,6 +14,8 @@ // // Aegisub Project http://www.aegisub.org/ +#pragma once + #include "visual_feature.h" #include "visual_tool.h" #include "spline.h" @@ -51,10 +53,6 @@ class VisualToolVectorClip final : public VisualTool box_added; - /// @brief Set the mode - /// @param mode 0-7 - void SetMode(VisualToolVectorClipMode mode); - void Save(); void Commit(wxString message="") override; @@ -73,4 +71,10 @@ class VisualToolVectorClip final : public VisualTool Date: Tue, 12 Jul 2022 15:59:18 +0200 Subject: [PATCH 3/7] Use command metadata for vector clip toolbar This cuts down on the data duplication for the command names and help texts, at the expense of copying a bit of code from the general toolbar logic. Modifying the toolbar Populate() function to also add additional buttons appears very hard or impossible. --- src/command/command.h | 2 ++ src/visual_tool_vector_clip.cpp | 40 +++++++++++++++++++++++---------- src/visual_tool_vector_clip.h | 3 +++ 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/src/command/command.h b/src/command/command.h index 08752adbe..4d7b00225 100644 --- a/src/command/command.h +++ b/src/command/command.h @@ -16,6 +16,8 @@ /// @brief Command base class and main header. /// @ingroup command +#pragma once + #include #include #include diff --git a/src/visual_tool_vector_clip.cpp b/src/visual_tool_vector_clip.cpp index 8cae6b513..b14aa81b5 100644 --- a/src/visual_tool_vector_clip.cpp +++ b/src/visual_tool_vector_clip.cpp @@ -38,24 +38,40 @@ 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->StrHelp(), wxITEM_CHECK); +} + + void VisualToolVectorClip::SetToolbar(wxToolBar *toolBar) { this->toolBar = toolBar; 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->AddTool(BUTTON_ID_BASE + VCLIP_DRAG, _("Drag"), ICON(visual_vector_clip_drag), _("Drag control points"), wxITEM_CHECK); - toolBar->AddTool(BUTTON_ID_BASE + VCLIP_LINE, _("Line"), ICON(visual_vector_clip_line), _("Appends a line"), wxITEM_CHECK); - toolBar->AddTool(BUTTON_ID_BASE + VCLIP_BICUBIC, _("Bicubic"), ICON(visual_vector_clip_bicubic), _("Appends a bezier bicubic curve"), wxITEM_CHECK); - toolBar->AddSeparator(); - toolBar->AddTool(BUTTON_ID_BASE + VCLIP_CONVERT, _("Convert"), ICON(visual_vector_clip_convert), _("Converts a segment between line and bicubic"), wxITEM_CHECK); - toolBar->AddTool(BUTTON_ID_BASE + VCLIP_INSERT, _("Insert"), ICON(visual_vector_clip_insert), _("Inserts a control point"), wxITEM_CHECK); - toolBar->AddTool(BUTTON_ID_BASE + VCLIP_REMOVE, _("Remove"), ICON(visual_vector_clip_remove), _("Removes a control point"), wxITEM_CHECK); - toolBar->AddSeparator(); - toolBar->AddTool(BUTTON_ID_BASE + VCLIP_FREEHAND, _("Freehand"), ICON(visual_vector_clip_freehand), _("Draws a freehand shape"), wxITEM_CHECK); - toolBar->AddTool(BUTTON_ID_BASE + VCLIP_FREEHAND_SMOOTH, _("Freehand smooth"), ICON(visual_vector_clip_freehand_smooth), _("Draws a smoothed freehand shape"), wxITEM_CHECK); toolBar->ToggleTool(BUTTON_ID_BASE + VCLIP_DRAG, true); toolBar->Realize(); toolBar->Show(true); diff --git a/src/visual_tool_vector_clip.h b/src/visual_tool_vector_clip.h index 4f0c8d0be..c1ce99ed6 100644 --- a/src/visual_tool_vector_clip.h +++ b/src/visual_tool_vector_clip.h @@ -19,6 +19,7 @@ #include "visual_feature.h" #include "visual_tool.h" #include "spline.h" +#include "command/command.h" class wxToolBar; @@ -56,6 +57,8 @@ class VisualToolVectorClip final : public VisualTool Date: Tue, 12 Jul 2022 16:54:04 +0200 Subject: [PATCH 4/7] Show hotkeys for vector clip tools Move the function to generate toolbar tooltips listing hotkeys to the command class, so it can be used outside of toolbar.cpp . --- src/command/command.cpp | 13 +++++++++++++ src/command/command.h | 3 +++ src/toolbar.cpp | 13 +------------ src/visual_tool_vector_clip.cpp | 2 +- 4 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/command/command.cpp b/src/command/command.cpp index edc041b6a..d0419161c 100644 --- a/src/command/command.cpp +++ b/src/command/command.cpp @@ -19,6 +19,9 @@ #include +#include +#include "include/aegisub/hotkey.h" + #include namespace cmd { @@ -32,6 +35,16 @@ namespace cmd { return it; } + wxString Command::GetTooltip(std::string ht_context) const { + wxString ret = StrHelp(); + + std::vector hotkeys = hotkey::get_hotkey_strs(ht_context, name()); + if (!hotkeys.empty()) + ret += to_wx(" (" + boost::join(hotkeys, "/") + ")"); + + return ret; + } + void reg(std::unique_ptr cmd) { cmd_map[cmd->name()] = std::move(cmd); } diff --git a/src/command/command.h b/src/command/command.h index 4d7b00225..899cace05 100644 --- a/src/command/command.h +++ b/src/command/command.h @@ -103,6 +103,9 @@ DEFINE_EXCEPTION(CommandNotFound, CommandError); /// Short help string describing what the command does 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 /// @return Bitmask of CommandFlags virtual int Type() const { return COMMAND_NORMAL; } diff --git a/src/toolbar.cpp b/src/toolbar.cpp index 40c0a7769..ac2aecb25 100644 --- a/src/toolbar.cpp +++ b/src/toolbar.cpp @@ -30,7 +30,6 @@ #include #include -#include #include #include @@ -143,7 +142,7 @@ namespace { wxITEM_NORMAL; 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); needs_onidle = needs_onidle || flags != cmd::COMMAND_NORMAL; @@ -157,16 +156,6 @@ namespace { Realize(); } - wxString GetTooltip(cmd::Command *command) { - wxString ret = command->StrHelp(); - - std::vector hotkeys = hotkey::get_hotkey_strs(ht_context, command->name()); - if (!hotkeys.empty()) - ret += to_wx(" (" + boost::join(hotkeys, "/") + ")"); - - return ret; - } - public: 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)) diff --git a/src/visual_tool_vector_clip.cpp b/src/visual_tool_vector_clip.cpp index b14aa81b5..351f5757f 100644 --- a/src/visual_tool_vector_clip.cpp +++ b/src/visual_tool_vector_clip.cpp @@ -52,7 +52,7 @@ void VisualToolVectorClip::AddTool(std::string command_name, VisualToolVectorCli } int icon_size = OPT_GET("App/Toolbar Icon Size")->GetInt(); - toolBar->AddTool(BUTTON_ID_BASE + mode, command->StrDisplay(c), command->Icon(icon_size), command->StrHelp(), wxITEM_CHECK); + toolBar->AddTool(BUTTON_ID_BASE + mode, command->StrDisplay(c), command->Icon(icon_size), command->GetTooltip("Video"), wxITEM_CHECK); } From 238dbb386dd68825b2e65a9e3ce661e8eab5a745 Mon Sep 17 00:00:00 2001 From: arch1t3cht Date: Tue, 12 Jul 2022 20:27:56 +0200 Subject: [PATCH 5/7] Restrict color picker's screenshot to window This fixes issues like Aegisub/Aegisub#264 with taking screenshots on linux, especially with wxgtk3 or wayland. --- src/dialog_colorpicker.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/dialog_colorpicker.cpp b/src/dialog_colorpicker.cpp index 510d2a6ce..f6e080636 100644 --- a/src/dialog_colorpicker.cpp +++ b/src/dialog_colorpicker.cpp @@ -386,7 +386,13 @@ void ColorPickerScreenDropper::DropFromScreenXY(int x, int y) { wxMemoryDC capdc(capture); capdc.SetPen(*wxTRANSPARENT_PEN); #ifndef __WXMAC__ - wxScreenDC screen; + wxWindow *superparent = GetParent(); + while (superparent->GetParent() != nullptr) { + superparent = superparent->GetParent(); + } + superparent->ScreenToClient(&x, &y); + + wxWindowDC screen(superparent); capdc.StretchBlit(0, 0, resx * magnification, resy * magnification, &screen, x - resx / 2, y - resy / 2, resx, resy); #else From 2c296afdb8895cd26c649c28b3134165c047081e Mon Sep 17 00:00:00 2001 From: arch1t3cht Date: Mon, 18 Jul 2022 20:20:24 +0200 Subject: [PATCH 6/7] Add option to restrict color picker to window --- src/dialog_colorpicker.cpp | 20 +++++++++++++------- src/libresrc/default_config.json | 3 +++ src/libresrc/osx/default_config.json | 3 +++ src/preferences.cpp | 3 +++ 4 files changed, 22 insertions(+), 7 deletions(-) diff --git a/src/dialog_colorpicker.cpp b/src/dialog_colorpicker.cpp index f6e080636..a9f20afef 100644 --- a/src/dialog_colorpicker.cpp +++ b/src/dialog_colorpicker.cpp @@ -386,15 +386,21 @@ void ColorPickerScreenDropper::DropFromScreenXY(int x, int y) { wxMemoryDC capdc(capture); capdc.SetPen(*wxTRANSPARENT_PEN); #ifndef __WXMAC__ - wxWindow *superparent = GetParent(); - while (superparent->GetParent() != nullptr) { - superparent = superparent->GetParent(); - } - superparent->ScreenToClient(&x, &y); + std::unique_ptr screen; - wxWindowDC screen(superparent); + if (!OPT_GET("Tool/Color Picker/Restrict to Window")->GetBool()) { + screen = agi::make_unique(); + } else { + wxWindow *superparent = GetParent(); + while (superparent->GetParent() != nullptr) { + superparent = superparent->GetParent(); + } + superparent->ScreenToClient(&x, &y); + + screen = agi::make_unique(superparent); + } 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 // wxScreenDC doesn't work on recent versions of OS X so do it manually diff --git a/src/libresrc/default_config.json b/src/libresrc/default_config.json index 318f8d3ee..7b8e9228e 100644 --- a/src/libresrc/default_config.json +++ b/src/libresrc/default_config.json @@ -573,6 +573,9 @@ "Maximized" : false, "Skip Whitespace" : true }, + "Color Picker" : { + "Restrict to Window" : false + }, "Visual" : { "Autohide": false } diff --git a/src/libresrc/osx/default_config.json b/src/libresrc/osx/default_config.json index 59f2ed05f..9e89707b5 100644 --- a/src/libresrc/osx/default_config.json +++ b/src/libresrc/osx/default_config.json @@ -573,6 +573,9 @@ "Maximized" : false, "Skip Whitespace" : true }, + "Color Picker" : { + "Restrict to Window" : false + }, "Visual" : { "Autohide": false } diff --git a/src/preferences.cpp b/src/preferences.cpp index f6320dd75..d595caa63 100644 --- a/src/preferences.cpp +++ b/src/preferences.cpp @@ -228,6 +228,9 @@ void Interface(wxTreebook *book, Preferences *parent) { auto tl_assistant = p->PageSizer(_("Translation Assistant")); 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); } From 7ea9b95fe04fe8f9fcf36462350ca6da2c8bf31c Mon Sep 17 00:00:00 2001 From: arch1t3cht Date: Tue, 19 Jul 2022 02:45:04 +0200 Subject: [PATCH 7/7] Clean up pointer code The previous one was remnant of scrapped code. --- src/command/vis_tool.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/command/vis_tool.cpp b/src/command/vis_tool.cpp index c898d87f3..fcf02f492 100644 --- a/src/command/vis_tool.cpp +++ b/src/command/vis_tool.cpp @@ -63,8 +63,7 @@ namespace { } void operator()(agi::Context *c) override { - std::unique_ptr vclip = agi::make_unique(c->videoDisplay, c); - c->videoDisplay->SetTool(std::move(vclip)); + c->videoDisplay->SetTool(agi::make_unique(c->videoDisplay, c)); c->videoDisplay->SetVectorClipTool(M); } };