Added lasso select tool
This commit is contained in:
parent
d6d51129ed
commit
a4ba969e11
7 changed files with 721 additions and 29 deletions
|
|
@ -21,9 +21,13 @@
|
|||
#include <include/core/SkSurface.h>
|
||||
#include "../World.hpp"
|
||||
#include "../MainProgram.hpp"
|
||||
#include "LassoSelectTool.hpp"
|
||||
#include <Helpers/Logger.hpp>
|
||||
#include <Helpers/Parallel.hpp>
|
||||
#include <cereal/types/unordered_set.hpp>
|
||||
#include <include/core/SkPathEffect.h>
|
||||
#include <include/effects/SkDashPathEffect.h>
|
||||
#include <chrono>
|
||||
|
||||
DrawingProgram::DrawingProgram(World& initWorld):
|
||||
world(initWorld),
|
||||
|
|
@ -32,6 +36,7 @@ DrawingProgram::DrawingProgram(World& initWorld):
|
|||
brushTool(*this),
|
||||
eraserTool(*this),
|
||||
rectSelectTool(*this),
|
||||
lassoSelectTool(*this),
|
||||
rectDrawTool(*this),
|
||||
ellipseDrawTool(*this),
|
||||
textBoxTool(*this),
|
||||
|
|
@ -200,6 +205,7 @@ void DrawingProgram::toolbar_gui() {
|
|||
if(t.gui.svg_icon_button("Ellipse Toolbar Button", "data/icons/circle.svg", controls.selectedTool == TOOL_ELLIPSE)) { controls.selectedTool = TOOL_ELLIPSE; }
|
||||
if(t.gui.svg_icon_button("Rect Toolbar Button", "data/icons/rectangle.svg", controls.selectedTool == TOOL_RECTANGLE)) { controls.selectedTool = TOOL_RECTANGLE; }
|
||||
if(t.gui.svg_icon_button("RectSelect Toolbar Button", "data/icons/rectselect.svg", controls.selectedTool == TOOL_RECTSELECT)) { controls.selectedTool = TOOL_RECTSELECT; }
|
||||
if(t.gui.svg_icon_button("LassoSelect Toolbar Button", "data/icons/close.svg", controls.selectedTool == TOOL_LASSOSELECT)) { controls.selectedTool = TOOL_LASSOSELECT; }
|
||||
if(t.gui.svg_icon_button("Edit Toolbar Button", "data/icons/cursor.svg", controls.selectedTool == TOOL_EDIT)) { controls.selectedTool = TOOL_EDIT; }
|
||||
if(t.gui.svg_icon_button("Inkdropper Toolbar Button", "data/icons/eyedropper.svg", controls.selectedTool == TOOL_INKDROPPER)) { controls.selectedTool = TOOL_INKDROPPER; }
|
||||
if(t.gui.svg_icon_button("Screenshot Toolbar Button", "data/icons/camera.svg", controls.selectedTool == TOOL_SCREENSHOT)) { controls.selectedTool = TOOL_SCREENSHOT; }
|
||||
|
|
@ -238,6 +244,9 @@ void DrawingProgram::tool_options_gui() {
|
|||
case TOOL_ERASER:
|
||||
eraserTool.gui_toolbox();
|
||||
break;
|
||||
case TOOL_LASSOSELECT:
|
||||
lassoSelectTool.gui_toolbox();
|
||||
break;
|
||||
case TOOL_RECTSELECT:
|
||||
rectSelectTool.gui_toolbox();
|
||||
break;
|
||||
|
|
@ -259,8 +268,6 @@ void DrawingProgram::tool_options_gui() {
|
|||
case TOOL_EDIT:
|
||||
editTool.gui_toolbox();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -335,6 +342,9 @@ void DrawingProgram::update() {
|
|||
case TOOL_ERASER:
|
||||
eraserTool.tool_update();
|
||||
break;
|
||||
case TOOL_LASSOSELECT:
|
||||
lassoSelectTool.tool_update();
|
||||
break;
|
||||
case TOOL_RECTSELECT:
|
||||
rectSelectTool.tool_update();
|
||||
break;
|
||||
|
|
@ -356,8 +366,6 @@ void DrawingProgram::update() {
|
|||
case TOOL_EDIT:
|
||||
editTool.tool_update();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
};
|
||||
|
||||
if(controls.leftClickReleased)
|
||||
|
|
@ -382,6 +390,8 @@ bool DrawingProgram::prevent_undo_or_redo() {
|
|||
return brushTool.prevent_undo_or_redo();
|
||||
case TOOL_ERASER:
|
||||
return eraserTool.prevent_undo_or_redo();
|
||||
case TOOL_LASSOSELECT:
|
||||
return lassoSelectTool.prevent_undo_or_redo();
|
||||
case TOOL_RECTSELECT:
|
||||
return rectSelectTool.prevent_undo_or_redo();
|
||||
case TOOL_RECTANGLE:
|
||||
|
|
@ -396,12 +406,24 @@ bool DrawingProgram::prevent_undo_or_redo() {
|
|||
return screenshotTool.prevent_undo_or_redo();
|
||||
case TOOL_EDIT:
|
||||
return editTool.prevent_undo_or_redo();
|
||||
default:
|
||||
break;
|
||||
};
|
||||
return false;
|
||||
}
|
||||
|
||||
SkPaint DrawingProgram::select_tool_line_paint() {
|
||||
SkScalar intervals[] = {10, 5};
|
||||
float timeSinceEpoch = std::chrono::duration_cast<std::chrono::duration<float>>(std::chrono::steady_clock::now().time_since_epoch()).count();
|
||||
sk_sp<SkPathEffect> lassoLineDashEffect = SkDashPathEffect::Make(intervals, 2, -std::fmod(timeSinceEpoch * 50, 15));
|
||||
|
||||
SkPaint selectLinePaint;
|
||||
selectLinePaint.setStyle(SkPaint::kStroke_Style);
|
||||
selectLinePaint.setStrokeWidth(3);
|
||||
selectLinePaint.setColor4f(world.canvasTheme.toolFrontColor);
|
||||
selectLinePaint.setPathEffect(lassoLineDashEffect);
|
||||
|
||||
return selectLinePaint;
|
||||
}
|
||||
|
||||
void DrawingProgram::force_rebuild_cache() {
|
||||
if(controls.selectedTool == TOOL_ERASER)
|
||||
compCache.test_rebuild_dont_include_set_dont_include_nodes(components.client_list(), eraserTool.erasedComponents, eraserTool.erasedBVHNodes, true);
|
||||
|
|
@ -477,6 +499,7 @@ void DrawingProgram::add_file_to_canvas_by_data(const std::string& fileName, std
|
|||
}
|
||||
|
||||
void DrawingProgram::reset_tools() {
|
||||
lassoSelectTool.reset_tool();
|
||||
rectSelectTool.reset_tool();
|
||||
textBoxTool.reset_tool();
|
||||
brushTool.reset_tool();
|
||||
|
|
@ -689,6 +712,9 @@ void DrawingProgram::draw(SkCanvas* canvas, const DrawData& drawData) {
|
|||
case TOOL_ERASER:
|
||||
eraserTool.draw(canvas, drawData);
|
||||
break;
|
||||
case TOOL_LASSOSELECT:
|
||||
lassoSelectTool.draw(canvas, drawData);
|
||||
break;
|
||||
case TOOL_RECTSELECT:
|
||||
rectSelectTool.draw(canvas, drawData);
|
||||
break;
|
||||
|
|
@ -710,8 +736,6 @@ void DrawingProgram::draw(SkCanvas* canvas, const DrawData& drawData) {
|
|||
case TOOL_EDIT:
|
||||
editTool.draw(canvas, drawData);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
#include "BrushTool.hpp"
|
||||
#include "EraserTool.hpp"
|
||||
#include "RectSelectTool.hpp"
|
||||
#include "LassoSelectTool.hpp"
|
||||
#include "RectDrawTool.hpp"
|
||||
#include "EllipseDrawTool.hpp"
|
||||
#include "TextBoxTool.hpp"
|
||||
|
|
@ -84,9 +85,13 @@ class DrawingProgram {
|
|||
void add_undo_place_components(const std::unordered_set<CollabListType::ObjectInfoPtr>& objSetToUndo);
|
||||
void add_undo_erase_components(const std::unordered_set<CollabListType::ObjectInfoPtr>& objSetToUndo);
|
||||
|
||||
SkPaint select_tool_line_paint();
|
||||
|
||||
|
||||
BrushTool brushTool;
|
||||
EraserTool eraserTool;
|
||||
RectSelectTool rectSelectTool;
|
||||
LassoSelectTool lassoSelectTool;
|
||||
RectDrawTool rectDrawTool;
|
||||
EllipseDrawTool ellipseDrawTool;
|
||||
TextBoxTool textBoxTool;
|
||||
|
|
@ -102,6 +107,7 @@ class DrawingProgram {
|
|||
enum Tool : int {
|
||||
TOOL_BRUSH = 0,
|
||||
TOOL_ERASER,
|
||||
TOOL_LASSOSELECT,
|
||||
TOOL_RECTSELECT,
|
||||
TOOL_RECTANGLE,
|
||||
TOOL_ELLIPSE,
|
||||
|
|
@ -142,4 +148,5 @@ class DrawingProgram {
|
|||
friend class ImageTool;
|
||||
friend class DrawingProgramCache;
|
||||
friend class DrawingProgramSelection;
|
||||
friend class LassoSelectTool;
|
||||
};
|
||||
|
|
|
|||
90
src/DrawingProgram/LassoSelectTool.cpp
Normal file
90
src/DrawingProgram/LassoSelectTool.cpp
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
#include "LassoSelectTool.hpp"
|
||||
#include "DrawingProgram.hpp"
|
||||
#include "../MainProgram.hpp"
|
||||
#include "../DrawData.hpp"
|
||||
#include "Helpers/MathExtras.hpp"
|
||||
#include "Helpers/SCollision.hpp"
|
||||
#include "../CoordSpaceHelper.hpp"
|
||||
#include <ranges>
|
||||
#include <delaunator.hpp>
|
||||
|
||||
LassoSelectTool::LassoSelectTool(DrawingProgram& initDrawP):
|
||||
drawP(initDrawP)
|
||||
{
|
||||
}
|
||||
|
||||
void LassoSelectTool::gui_toolbox() {
|
||||
drawP.world.main.toolbar.gui.text_label_centered("Lasso Select");
|
||||
}
|
||||
|
||||
void LassoSelectTool::reset_tool() {
|
||||
drawP.selection.deselect_all();
|
||||
controls = LassoSelectControls();
|
||||
}
|
||||
|
||||
void LassoSelectTool::tool_update() {
|
||||
switch(controls.selectionMode) {
|
||||
case 0: {
|
||||
if(drawP.controls.leftClick) {
|
||||
if(drawP.selection.is_something_selected()) {
|
||||
if(!drawP.selection.mouse_collided_with_selection())
|
||||
reset_tool();
|
||||
}
|
||||
else {
|
||||
reset_tool();
|
||||
controls.coords = drawP.world.drawData.cam.c;
|
||||
controls.lassoPoints.emplace_back(controls.coords.get_mouse_pos(drawP.world));
|
||||
controls.selectionMode = 1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
using namespace SCollision;
|
||||
Vector2f newLassoPoint = controls.coords.get_mouse_pos(drawP.world);
|
||||
if(vec_distance(controls.lassoPoints.back(), newLassoPoint)) {
|
||||
controls.lassoPoints.emplace_back(newLassoPoint);
|
||||
}
|
||||
if(!drawP.controls.leftClickHeld) {
|
||||
std::vector<double> dCoords;
|
||||
for(Vector2f& lassoPoint : controls.lassoPoints) {
|
||||
dCoords.emplace_back(lassoPoint.x());
|
||||
dCoords.emplace_back(lassoPoint.y());
|
||||
}
|
||||
delaunator::Delaunator d(dCoords);
|
||||
ColliderCollection<float> cC;
|
||||
for(size_t i = 0; i < d.triangles.size(); i += 3) {
|
||||
SCollision::Triangle tri{
|
||||
Vector2f{dCoords[2 * d.triangles[i]], dCoords[2 * d.triangles[i] + 1]},
|
||||
Vector2f{dCoords[2 * d.triangles[i + 1]], dCoords[2 * d.triangles[i + 1] + 1]},
|
||||
Vector2f{dCoords[2 * d.triangles[i + 2]], dCoords[2 * d.triangles[i + 2] + 1]}
|
||||
};
|
||||
cC.triangle.emplace_back(tri);
|
||||
}
|
||||
drawP.selection.add_from_cam_coord_collider_to_selection(cC);
|
||||
controls.selectionMode = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool LassoSelectTool::prevent_undo_or_redo() {
|
||||
return drawP.selection.is_something_selected() || controls.selectionMode == 1;
|
||||
}
|
||||
|
||||
void LassoSelectTool::draw(SkCanvas* canvas, const DrawData& drawData) {
|
||||
if(controls.selectionMode == 1) {
|
||||
canvas->save();
|
||||
controls.coords.transform_sk_canvas(canvas, drawData);
|
||||
|
||||
SkPath lassoPath;
|
||||
lassoPath.moveTo(convert_vec2<SkPoint>(controls.lassoPoints.front()));
|
||||
for(Vector2f& p : controls.lassoPoints | std::views::drop(1))
|
||||
lassoPath.lineTo(convert_vec2<SkPoint>(p));
|
||||
|
||||
canvas->drawPath(lassoPath, drawP.select_tool_line_paint());
|
||||
|
||||
canvas->restore();
|
||||
}
|
||||
}
|
||||
29
src/DrawingProgram/LassoSelectTool.hpp
Normal file
29
src/DrawingProgram/LassoSelectTool.hpp
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#pragma once
|
||||
#include <include/core/SkCanvas.h>
|
||||
#include "../DrawData.hpp"
|
||||
#include <Helpers/SCollision.hpp>
|
||||
#include "../CoordSpaceHelper.hpp"
|
||||
#include "../DrawComponents/DrawComponent.hpp"
|
||||
|
||||
class DrawingProgram;
|
||||
|
||||
class LassoSelectTool {
|
||||
public:
|
||||
LassoSelectTool(DrawingProgram& initDrawP);
|
||||
void gui_toolbox();
|
||||
void tool_update();
|
||||
void draw(SkCanvas* canvas, const DrawData& drawData);
|
||||
void reset_tool();
|
||||
|
||||
bool prevent_undo_or_redo();
|
||||
private:
|
||||
struct LassoSelectControls {
|
||||
int selectionMode = 0;
|
||||
|
||||
CoordSpaceHelper coords;
|
||||
|
||||
std::vector<Vector2f> lassoPoints;
|
||||
} controls;
|
||||
|
||||
DrawingProgram& drawP;
|
||||
};
|
||||
|
|
@ -1,27 +1,10 @@
|
|||
#include "RectSelectTool.hpp"
|
||||
#include <chrono>
|
||||
#include "DrawingProgram.hpp"
|
||||
#include "../Server/CommandList.hpp"
|
||||
#include "../MainProgram.hpp"
|
||||
#include "../DrawData.hpp"
|
||||
#include "Helpers/FixedPoint.hpp"
|
||||
#include "Helpers/MathExtras.hpp"
|
||||
#include "Helpers/SCollision.hpp"
|
||||
#include "Helpers/Serializers.hpp"
|
||||
#include "../CoordSpaceHelper.hpp"
|
||||
#include <cereal/types/vector.hpp>
|
||||
#include <algorithm>
|
||||
#include <ranges>
|
||||
|
||||
#ifdef USE_SKIA_BACKEND_GRAPHITE
|
||||
#include <include/gpu/graphite/Surface.h>
|
||||
#elif USE_SKIA_BACKEND_GANESH
|
||||
#include <include/gpu/ganesh/GrDirectContext.h>
|
||||
#include <include/gpu/ganesh/SkSurfaceGanesh.h>
|
||||
#endif
|
||||
|
||||
#define ROTATION_POINT_RADIUS_MULTIPLIER 0.7
|
||||
#define ROTATION_POINTS_DISTANCE 20.0
|
||||
|
||||
RectSelectTool::RectSelectTool(DrawingProgram& initDrawP):
|
||||
drawP(initDrawP)
|
||||
|
|
@ -83,11 +66,8 @@ void RectSelectTool::draw(SkCanvas* canvas, const DrawData& drawData) {
|
|||
canvas->save();
|
||||
controls.coords.transform_sk_canvas(canvas, drawData);
|
||||
|
||||
SkPaint selectionPaint;
|
||||
selectionPaint.setColor4f({0.3f, 0.6f, 0.9f, 0.4f});
|
||||
|
||||
SkRect r = SkRect::MakeLTRB(controls.newT[0].x(), controls.newT[0].y(), controls.newT[2].x(), controls.newT[2].y());
|
||||
canvas->drawRect(r, selectionPaint);
|
||||
canvas->drawRect(r, drawP.select_tool_line_paint());
|
||||
canvas->restore();
|
||||
|
||||
canvas->restore();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue