Working on meshes
This commit is contained in:
parent
c479ccb9e2
commit
7b472fe18d
652 changed files with 81120 additions and 852 deletions
|
|
@ -400,6 +400,7 @@ void DrawingProgram::toolbar_gui(Toolbar& t) {
|
|||
|
||||
tool_button("Brush Toolbar Button", "data/icons/brush.svg", DrawingProgramToolType::BRUSH);
|
||||
tool_button("Eraser Toolbar Button", "data/icons/eraser.svg", DrawingProgramToolType::ERASER);
|
||||
tool_button("Fill Toolbar Button", "data/icons/RemixIcon/paint-line.svg", DrawingProgramToolType::FILL);
|
||||
tool_button("Line Toolbar Button", "data/icons/line.svg", DrawingProgramToolType::LINE);
|
||||
tool_button("Text Toolbar Button", "data/icons/text.svg", DrawingProgramToolType::TEXTBOX);
|
||||
tool_button("Ellipse Toolbar Button", "data/icons/circle.svg", DrawingProgramToolType::ELLIPSE);
|
||||
|
|
|
|||
|
|
@ -177,6 +177,7 @@ class DrawingProgram {
|
|||
friend class DrawingProgramCache;
|
||||
friend class DrawingProgramSelection;
|
||||
friend class LassoSelectTool;
|
||||
friend class FillTool;
|
||||
friend class GridEditTool;
|
||||
friend class GridModifyTool;
|
||||
friend class ZoomCanvasTool;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#include "../DrawingProgram.hpp"
|
||||
#include "../../MainProgram.hpp"
|
||||
#include "DrawingProgramToolBase.hpp"
|
||||
#include "../../CanvasComponents/BrushStrokeCanvasComponent.hpp"
|
||||
#include "../../CanvasComponents/MeshCanvasComponent.hpp"
|
||||
#include "Helpers/NetworkingObjects/NetObjTemporaryPtr.decl.hpp"
|
||||
#include "../../CanvasComponents/CanvasComponentContainer.hpp"
|
||||
|
||||
|
|
@ -53,9 +53,6 @@ void BrushTool::erase_component(CanvasComponentContainer::ObjInfo* erasedComp) {
|
|||
|
||||
void BrushTool::smooth_out_points(float smoothFactor) {
|
||||
if(objInfoBeingEdited) {
|
||||
NetworkingObjects::NetObjOwnerPtr<CanvasComponentContainer>& containerPtr = objInfoBeingEdited->obj;
|
||||
BrushStrokeCanvasComponent& brushStroke = static_cast<BrushStrokeCanvasComponent&>(containerPtr->get_comp());
|
||||
auto& brushPoints = *brushStroke.d.points;
|
||||
if(brushPoints.size() >= 2) {
|
||||
brushPoints.back().width = std::max(brushPoints[brushPoints.size() - 1].width, brushPoints[brushPoints.size() - 2].width * smoothFactor);
|
||||
for(size_t i = brushPoints.size() - 1; i > 0; i--) {
|
||||
|
|
@ -70,12 +67,8 @@ void BrushTool::smooth_out_points(float smoothFactor) {
|
|||
|
||||
void BrushTool::fix_tip() {
|
||||
if(objInfoBeingEdited) {
|
||||
NetworkingObjects::NetObjOwnerPtr<CanvasComponentContainer>& containerPtr = objInfoBeingEdited->obj;
|
||||
BrushStrokeCanvasComponent& brushStroke = static_cast<BrushStrokeCanvasComponent&>(containerPtr->get_comp());
|
||||
auto& brushPoints = *brushStroke.d.points;
|
||||
if(brushPoints.size() >= 2) {
|
||||
if(brushPoints.size() >= 2)
|
||||
brushPoints[brushPoints.size() - 2].width = brushPoints[brushPoints.size() - 1].width = std::max(brushPoints[brushPoints.size() - 1].width, brushPoints[brushPoints.size() - 2].width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -100,18 +93,19 @@ void BrushTool::input_mouse_button_on_canvas_callback(const InputManager::MouseB
|
|||
}
|
||||
float width = relativeWidthResult.first.value() * penWidth;
|
||||
|
||||
CanvasComponentContainer* newBrushStrokeContainer = new CanvasComponentContainer(drawP.world.netObjMan, CanvasComponentType::BRUSHSTROKE);
|
||||
BrushStrokeCanvasComponent& newBrushStroke = static_cast<BrushStrokeCanvasComponent&>(newBrushStrokeContainer->get_comp());
|
||||
CanvasComponentContainer* newMeshContainer = new CanvasComponentContainer(drawP.world.netObjMan, CanvasComponentType::MESH);
|
||||
MeshCanvasComponent& newMesh = static_cast<MeshCanvasComponent&>(newMeshContainer->get_comp());
|
||||
|
||||
BrushStrokeCanvasComponentPoint p;
|
||||
brushPoints.clear();
|
||||
BrushComponentCode::BrushPoint p;
|
||||
p.pos = button.pos;
|
||||
p.width = width;
|
||||
prevPointUnaltered = p.pos;
|
||||
newBrushStroke.d.points->emplace_back(p);
|
||||
newBrushStroke.d.color = toolConfig.globalConf.foregroundColor;
|
||||
newBrushStroke.d.hasRoundCaps = toolConfig.brush.hasRoundCaps;
|
||||
newBrushStrokeContainer->coords = drawP.world.drawData.cam.c;
|
||||
objInfoBeingEdited = drawP.layerMan.add_component_to_layer_being_edited(newBrushStrokeContainer);
|
||||
brushPoints.emplace_back(p);
|
||||
newMesh.d.color = toolConfig.globalConf.foregroundColor;
|
||||
newMeshContainer->coords = drawP.world.drawData.cam.c;
|
||||
objInfoBeingEdited = drawP.layerMan.add_component_to_layer_being_edited(newMeshContainer);
|
||||
commit_data(false);
|
||||
addedTemporaryPoint = false;
|
||||
}
|
||||
else if(!button.down && objInfoBeingEdited)
|
||||
|
|
@ -119,22 +113,30 @@ void BrushTool::input_mouse_button_on_canvas_callback(const InputManager::MouseB
|
|||
}
|
||||
}
|
||||
|
||||
void BrushTool::commit_data(bool final) {
|
||||
if(objInfoBeingEdited) {
|
||||
NetworkingObjects::NetObjOwnerPtr<CanvasComponentContainer>& containerPtr = objInfoBeingEdited->obj;
|
||||
MeshCanvasComponent& newMesh = static_cast<MeshCanvasComponent&>(containerPtr->get_comp());
|
||||
newMesh.d.points = BrushComponentCode::brush_stroke_to_mesh_points(brushPoints, drawP.world.main.toolConfig.brush.hasRoundCaps);
|
||||
containerPtr->commit_update(drawP);
|
||||
containerPtr->send_comp_update(drawP, final);
|
||||
}
|
||||
}
|
||||
|
||||
void BrushTool::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) {
|
||||
if(objInfoBeingEdited) {
|
||||
auto& toolConfig = drawP.world.main.toolConfig;
|
||||
NetworkingObjects::NetObjOwnerPtr<CanvasComponentContainer>& containerPtr = objInfoBeingEdited->obj;
|
||||
BrushStrokeCanvasComponent& brushStroke = static_cast<BrushStrokeCanvasComponent&>(containerPtr->get_comp());
|
||||
auto& brushPoints = *brushStroke.d.points;
|
||||
float width = toolConfig.get_relative_width_stroke_size(drawP, containerPtr->coords.inverseScale).first.value() * penWidth;
|
||||
|
||||
BrushStrokeCanvasComponentPoint p;
|
||||
BrushComponentCode::BrushPoint p;
|
||||
p.pos = containerPtr->coords.from_cam_space_to_this(drawP.world, motion.pos);
|
||||
p.width = width;
|
||||
|
||||
// Temporary point is a point that follows the cursor until it is placed
|
||||
if(!addedTemporaryPoint) {
|
||||
// Temporary point is close enough to be placed
|
||||
if(extensive_point_checking(brushStroke, p.pos)) {
|
||||
if(extensive_point_checking(p.pos)) {
|
||||
brushPoints.emplace_back(p);
|
||||
addedTemporaryPoint = true;
|
||||
}
|
||||
|
|
@ -144,10 +146,10 @@ void BrushTool::input_mouse_motion_callback(const InputManager::MouseMotionCallb
|
|||
}
|
||||
|
||||
if(addedTemporaryPoint) {
|
||||
const BrushStrokeCanvasComponentPoint& prevP = brushPoints[brushPoints.size() - 2];
|
||||
const BrushComponentCode::BrushPoint& prevP = brushPoints[brushPoints.size() - 2];
|
||||
float distToPrev = (p.pos - prevP.pos).norm();
|
||||
// If the cursor isnt too close to the previous points, move the temporary point to the cursor and change the width of the temporary point to the current pen width
|
||||
if(extensive_point_checking_back(brushStroke, p.pos)) {
|
||||
if(extensive_point_checking_back(p.pos)) {
|
||||
brushPoints.back().pos = p.pos;
|
||||
brushPoints.back().width = std::max(brushPoints.back().width, p.width);
|
||||
}
|
||||
|
|
@ -186,8 +188,6 @@ void BrushTool::input_pen_axis_callback(const InputManager::PenAxisCallbackArgs&
|
|||
if(objInfoBeingEdited) {
|
||||
auto& toolConfig = drawP.world.main.toolConfig;
|
||||
NetworkingObjects::NetObjOwnerPtr<CanvasComponentContainer>& containerPtr = objInfoBeingEdited->obj;
|
||||
BrushStrokeCanvasComponent& brushStroke = static_cast<BrushStrokeCanvasComponent&>(containerPtr->get_comp());
|
||||
auto& brushPoints = *brushStroke.d.points;
|
||||
float width = toolConfig.get_relative_width_stroke_size(drawP, containerPtr->coords.inverseScale).first.value() * penWidth;
|
||||
brushPoints.back().width = std::max(brushPoints.back().width, width);
|
||||
smooth_out_points(drawP.world.main.conf.tabletOptions.brushPressureSmoothingFactor);
|
||||
|
|
@ -197,8 +197,8 @@ void BrushTool::input_pen_axis_callback(const InputManager::PenAxisCallbackArgs&
|
|||
}
|
||||
}
|
||||
|
||||
bool BrushTool::extensive_point_checking(const BrushStrokeCanvasComponent& brushStroke, const Vector2f& newPoint) {
|
||||
auto& points = *brushStroke.d.points;
|
||||
bool BrushTool::extensive_point_checking(const Vector2f& newPoint) {
|
||||
auto& points = brushPoints;
|
||||
if(points.size() >= 1 && (newPoint - points[points.size() - 1].pos).norm() < MINIMUM_DISTANCE_TO_NEXT_POINT)
|
||||
return false;
|
||||
if(points.size() >= 2 && (newPoint - points[points.size() - 2].pos).norm() < MINIMUM_DISTANCE_TO_NEXT_POINT)
|
||||
|
|
@ -208,8 +208,8 @@ bool BrushTool::extensive_point_checking(const BrushStrokeCanvasComponent& brush
|
|||
return true;
|
||||
}
|
||||
|
||||
bool BrushTool::extensive_point_checking_back(const BrushStrokeCanvasComponent& brushStroke, const Vector2f& newPoint) {
|
||||
auto& points = *brushStroke.d.points;
|
||||
bool BrushTool::extensive_point_checking_back(const Vector2f& newPoint) {
|
||||
auto& points = brushPoints;
|
||||
if(points.size() >= 2 && (newPoint - points[points.size() - 2].pos).norm() < MINIMUM_DISTANCE_TO_NEXT_POINT)
|
||||
return false;
|
||||
if(points.size() >= 3 && (newPoint - points[points.size() - 3].pos).norm() < MINIMUM_DISTANCE_TO_NEXT_POINT)
|
||||
|
|
@ -224,9 +224,7 @@ void BrushTool::tool_update() {
|
|||
drawP.world.main.input.hideCursor = true;
|
||||
|
||||
if(commitUpdate && objInfoBeingEdited) {
|
||||
NetworkingObjects::NetObjOwnerPtr<CanvasComponentContainer>& containerPtr = objInfoBeingEdited->obj;
|
||||
containerPtr->commit_update(drawP);
|
||||
containerPtr->send_comp_update(drawP, false);
|
||||
commit_data(false);
|
||||
commitUpdate = false;
|
||||
}
|
||||
}
|
||||
|
|
@ -235,8 +233,7 @@ void BrushTool::commit_stroke() {
|
|||
if(objInfoBeingEdited) {
|
||||
NetworkingObjects::NetObjOwnerPtr<CanvasComponentContainer>& containerPtr = objInfoBeingEdited->obj;
|
||||
fix_tip();
|
||||
containerPtr->commit_update(drawP);
|
||||
containerPtr->send_comp_update(drawP, true);
|
||||
commit_data(true);
|
||||
commitUpdate = false;
|
||||
if(containerPtr->get_world_bounds().has_value())
|
||||
drawP.layerMan.add_undo_place_component(objInfoBeingEdited);
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@
|
|||
#include <include/core/SkCanvas.h>
|
||||
#include "../../CanvasComponents/CanvasComponentContainer.hpp"
|
||||
#include <Helpers/NetworkingObjects/NetObjWeakPtr.hpp>
|
||||
#include "../../CanvasComponents/BrushComponentCode.hpp"
|
||||
|
||||
class DrawingProgram;
|
||||
struct DrawData;
|
||||
|
|
@ -46,16 +47,19 @@ class BrushTool : public DrawingProgramToolBase {
|
|||
virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) override;
|
||||
virtual void input_pen_axis_callback(const InputManager::PenAxisCallbackArgs& axis) override;
|
||||
private:
|
||||
bool extensive_point_checking_back(const BrushStrokeCanvasComponent& brushStroke, const Vector2f& newPoint);
|
||||
bool extensive_point_checking(const BrushStrokeCanvasComponent& brushStroke, const Vector2f& newPoint);
|
||||
bool extensive_point_checking_back(const Vector2f& newPoint);
|
||||
bool extensive_point_checking(const Vector2f& newPoint);
|
||||
void smooth_out_points(float smoothFactor);
|
||||
void fix_tip();
|
||||
void commit_stroke();
|
||||
void commit_data(bool final);
|
||||
|
||||
float penWidth = 1.0f;
|
||||
bool addedTemporaryPoint = false;
|
||||
bool commitUpdate = false;
|
||||
|
||||
std::vector<BrushComponentCode::BrushPoint> brushPoints;
|
||||
|
||||
CanvasComponentContainer::ObjInfo* objInfoBeingEdited = nullptr;
|
||||
|
||||
Vector2f prevPointUnaltered = {0, 0};
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "BrushTool.hpp"
|
||||
#include "EraserTool.hpp"
|
||||
#include "FillTool.hpp"
|
||||
#include "PanCanvasTool.hpp"
|
||||
#include "RectSelectTool.hpp"
|
||||
#include "LassoSelectTool.hpp"
|
||||
|
|
@ -45,6 +46,8 @@ std::unique_ptr<DrawingProgramToolBase> DrawingProgramToolBase::allocate_tool_ty
|
|||
return std::make_unique<BrushTool>(drawP);
|
||||
case DrawingProgramToolType::ERASER:
|
||||
return std::make_unique<EraserTool>(drawP);
|
||||
case DrawingProgramToolType::FILL:
|
||||
return std::make_unique<FillTool>(drawP);
|
||||
case DrawingProgramToolType::LASSOSELECT:
|
||||
return std::make_unique<LassoSelectTool>(drawP);
|
||||
case DrawingProgramToolType::RECTSELECT:
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@ class PhoneDrawingProgramScreen;
|
|||
enum class DrawingProgramToolType : int {
|
||||
BRUSH = 0,
|
||||
ERASER,
|
||||
FILL,
|
||||
LASSOSELECT,
|
||||
RECTSELECT,
|
||||
RECTANGLE,
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
#include "EditTools/RectDrawEditTool.hpp"
|
||||
#include "EditTools/ImageEditTool.hpp"
|
||||
#include "EditTools/EllipseDrawEditTool.hpp"
|
||||
#include "EditTools/BrushEditTool.hpp"
|
||||
#include "EditTools/MeshEditTool.hpp"
|
||||
|
||||
#include "../../GUIStuff/ElementHelpers/TextLabelHelpers.hpp"
|
||||
|
||||
|
|
@ -294,8 +294,8 @@ void EditTool::edit_start(CanvasComponentContainer::ObjInfo* comp, bool initUndo
|
|||
compEditTool = std::make_unique<ImageEditTool>(drawP, comp);
|
||||
break;
|
||||
}
|
||||
case CanvasComponentType::BRUSHSTROKE: {
|
||||
compEditTool = std::make_unique<BrushEditTool>(drawP, comp);
|
||||
case CanvasComponentType::MESH: {
|
||||
compEditTool = std::make_unique<MeshEditTool>(drawP, comp);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
|
|
|||
|
|
@ -16,67 +16,67 @@
|
|||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "BrushEditTool.hpp"
|
||||
#include "MeshEditTool.hpp"
|
||||
#include "../../DrawingProgram.hpp"
|
||||
#include "../../../World.hpp"
|
||||
#include "../../../MainProgram.hpp"
|
||||
#include "../EditTool.hpp"
|
||||
#include "../../../CanvasComponents/BrushStrokeCanvasComponent.hpp"
|
||||
#include "../../../CanvasComponents/MeshCanvasComponent.hpp"
|
||||
|
||||
#include "../../../GUIStuff/ElementHelpers/TextLabelHelpers.hpp"
|
||||
#include "../../../GUIStuff/ElementHelpers/LayoutHelpers.hpp"
|
||||
|
||||
BrushEditTool::BrushEditTool(DrawingProgram& initDrawP, CanvasComponentContainer::ObjInfo* initComp):
|
||||
MeshEditTool::MeshEditTool(DrawingProgram& initDrawP, CanvasComponentContainer::ObjInfo* initComp):
|
||||
DrawingProgramEditToolBase(initDrawP, initComp)
|
||||
{}
|
||||
|
||||
void BrushEditTool::edit_gui(Toolbar& t) {
|
||||
void MeshEditTool::edit_gui(Toolbar& t) {
|
||||
using namespace GUIStuff;
|
||||
using namespace ElementHelpers;
|
||||
|
||||
auto& a = static_cast<BrushStrokeCanvasComponent&>(comp->obj->get_comp());
|
||||
auto& a = static_cast<MeshCanvasComponent&>(comp->obj->get_comp());
|
||||
auto& gui = drawP.world.main.g.gui;
|
||||
auto commit_update_func = [&] { commitUpdate = true; };
|
||||
|
||||
gui.new_id("edit tool brush", [&] {
|
||||
text_label_centered(gui, "Edit Brush Stroke");
|
||||
gui.new_id("edit tool mesh", [&] {
|
||||
text_label_centered(gui, "Edit Mesh");
|
||||
left_to_right_line_layout(gui, [&]() {
|
||||
t.color_button_right("Outline Color", &a.d.color, { .onChange = commit_update_func });
|
||||
text_label(gui, "Outline Color");
|
||||
t.color_button_right("Mesh Color", &a.d.color, { .onChange = commit_update_func });
|
||||
text_label(gui, "Mesh Color");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void BrushEditTool::gui_phone_toolbox(PhoneDrawingProgramScreen& t) {
|
||||
void MeshEditTool::gui_phone_toolbox(PhoneDrawingProgramScreen& t) {
|
||||
using namespace GUIStuff;
|
||||
using namespace ElementHelpers;
|
||||
|
||||
auto& a = static_cast<BrushStrokeCanvasComponent&>(comp->obj->get_comp());
|
||||
auto& a = static_cast<MeshCanvasComponent&>(comp->obj->get_comp());
|
||||
auto& gui = drawP.world.main.g.gui;
|
||||
auto commit_update_func = [&] { commitUpdate = true; };
|
||||
|
||||
gui.new_id("edit tool brush", [&] {
|
||||
gui.new_id("edit tool mesh", [&] {
|
||||
left_to_right_line_layout(gui, [&]() {
|
||||
t.color_selector_button("Outline Color", &a.d.color, { .onChange = commit_update_func });
|
||||
text_label(gui, "Outline Color");
|
||||
t.color_selector_button("Mesh Color", &a.d.color, { .onChange = commit_update_func });
|
||||
text_label(gui, "Mesh Color");
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
Vector4f* BrushEditTool::color_picker_color(Vector4f* oldColor) {
|
||||
auto& a = static_cast<BrushStrokeCanvasComponent&>(comp->obj->get_comp());
|
||||
Vector4f* MeshEditTool::color_picker_color(Vector4f* oldColor) {
|
||||
auto& a = static_cast<MeshCanvasComponent&>(comp->obj->get_comp());
|
||||
if(oldColor == &a.d.color)
|
||||
return oldColor;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void BrushEditTool::edit_start(EditTool& editTool, std::any& prevData) {
|
||||
auto& a = static_cast<BrushStrokeCanvasComponent&>(comp->obj->get_comp());
|
||||
void MeshEditTool::edit_start(EditTool& editTool, std::any& prevData) {
|
||||
auto& a = static_cast<MeshCanvasComponent&>(comp->obj->get_comp());
|
||||
oldColor = a.d.color;
|
||||
}
|
||||
|
||||
void BrushEditTool::commit_edit_updates(std::any& prevData) {
|
||||
void MeshEditTool::commit_edit_updates(std::any& prevData) {
|
||||
}
|
||||
|
||||
void BrushEditTool::edit_update() {
|
||||
void MeshEditTool::edit_update() {
|
||||
}
|
||||
|
|
@ -23,9 +23,9 @@
|
|||
|
||||
class DrawingProgram;
|
||||
|
||||
class BrushEditTool : public DrawingProgramEditToolBase {
|
||||
class MeshEditTool : public DrawingProgramEditToolBase {
|
||||
public:
|
||||
BrushEditTool(DrawingProgram& initDrawP, CanvasComponentContainer::ObjInfo* initComp);
|
||||
MeshEditTool(DrawingProgram& initDrawP, CanvasComponentContainer::ObjInfo* initComp);
|
||||
virtual void edit_start(EditTool& editTool, std::any& prevData) override;
|
||||
virtual void commit_edit_updates(std::any& prevData) override;
|
||||
virtual void edit_update() override;
|
||||
98
src/DrawingProgram/Tools/FillTool.cpp
Normal file
98
src/DrawingProgram/Tools/FillTool.cpp
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* InfiniPaint
|
||||
* Copyright (C) 2025-2026 Yousef Khadadeh
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "FillTool.hpp"
|
||||
#include "../DrawingProgram.hpp"
|
||||
#include "../../MainProgram.hpp"
|
||||
#include "../../DrawData.hpp"
|
||||
#include "DrawingProgramToolBase.hpp"
|
||||
#include "../../CoordSpaceHelper.hpp"
|
||||
#include "../../GUIStuff/ElementHelpers/TextLabelHelpers.hpp"
|
||||
#include "../../CanvasComponents/MeshCanvasComponent.hpp"
|
||||
|
||||
FillTool::FillTool(DrawingProgram& initDrawP):
|
||||
DrawingProgramToolBase(initDrawP)
|
||||
{}
|
||||
|
||||
DrawingProgramToolType FillTool::get_type() {
|
||||
return DrawingProgramToolType::FILL;
|
||||
}
|
||||
|
||||
void FillTool::gui_toolbox(Toolbar& t) {
|
||||
auto& gui = drawP.world.main.g.gui;
|
||||
gui.new_id("fill tool", [&] {
|
||||
GUIStuff::ElementHelpers::text_label_centered(gui, "Fill");
|
||||
});
|
||||
}
|
||||
|
||||
void FillTool::gui_phone_toolbox(PhoneDrawingProgramScreen& t) {
|
||||
auto& gui = drawP.world.main.g.gui;
|
||||
gui.new_id("fill tool", [&] {
|
||||
});
|
||||
}
|
||||
|
||||
void FillTool::right_click_popup_gui(Toolbar& t, Vector2f popupPos) {
|
||||
drawP.selection_action_menu(popupPos);
|
||||
}
|
||||
|
||||
void FillTool::input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button) {
|
||||
if(button.button == InputManager::MouseButton::LEFT) {
|
||||
if(button.down && drawP.layerMan.is_a_layer_being_edited() && !drawP.world.main.g.gui.cursor_obstructed()) {
|
||||
auto& toolConfig = drawP.world.main.toolConfig;
|
||||
|
||||
CanvasComponentContainer* newContainer = new CanvasComponentContainer(drawP.world.netObjMan, CanvasComponentType::MESH);
|
||||
MeshCanvasComponent& newMesh = static_cast<MeshCanvasComponent&>(newContainer->get_comp());
|
||||
|
||||
newMesh.d.color = toolConfig.globalConf.foregroundColor;
|
||||
newMesh.d.points.fill.emplace_back();
|
||||
newMesh.d.points.fill.back().emplace_back(button.pos + Vector2f{0.0f, 100.0f});
|
||||
newMesh.d.points.fill.back().emplace_back(button.pos + Vector2f{-100.0f, -100.0f});
|
||||
newMesh.d.points.fill.back().emplace_back(button.pos + Vector2f{100.0f, -100.0f});
|
||||
newContainer->coords = drawP.world.drawData.cam.c;
|
||||
|
||||
objInfoBeingEdited = drawP.layerMan.add_component_to_layer_being_edited(newContainer);
|
||||
|
||||
objInfoBeingEdited->obj->commit_update(drawP);
|
||||
objInfoBeingEdited->obj->send_comp_update(drawP, true);
|
||||
|
||||
drawP.layerMan.add_undo_place_component(objInfoBeingEdited);
|
||||
|
||||
objInfoBeingEdited = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vector4f* FillTool::color_picker_color(Vector4f* oldColor) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void FillTool::erase_component(CanvasComponentContainer::ObjInfo* erasedComp) {
|
||||
}
|
||||
|
||||
void FillTool::switch_tool(DrawingProgramToolType newTool) {
|
||||
}
|
||||
|
||||
void FillTool::tool_update() {
|
||||
}
|
||||
|
||||
bool FillTool::prevent_undo_or_redo() {
|
||||
return false;
|
||||
}
|
||||
|
||||
void FillTool::draw(SkCanvas* canvas, const DrawData& drawData) {
|
||||
}
|
||||
44
src/DrawingProgram/Tools/FillTool.hpp
Normal file
44
src/DrawingProgram/Tools/FillTool.hpp
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* InfiniPaint
|
||||
* Copyright (C) 2025-2026 Yousef Khadadeh
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <include/core/SkCanvas.h>
|
||||
#include "../../DrawData.hpp"
|
||||
#include <Helpers/SCollision.hpp>
|
||||
#include "../../CoordSpaceHelper.hpp"
|
||||
#include "DrawingProgramToolBase.hpp"
|
||||
|
||||
class DrawingProgram;
|
||||
|
||||
class FillTool : public DrawingProgramToolBase {
|
||||
public:
|
||||
FillTool(DrawingProgram& initDrawP);
|
||||
virtual DrawingProgramToolType get_type() override;
|
||||
virtual void gui_toolbox(Toolbar& t) override;
|
||||
virtual void gui_phone_toolbox(PhoneDrawingProgramScreen& t) override;
|
||||
virtual void right_click_popup_gui(Toolbar& t, Vector2f popupPos) override;
|
||||
virtual void erase_component(CanvasComponentContainer::ObjInfo* erasedComp) override;
|
||||
virtual void tool_update() override;
|
||||
virtual void draw(SkCanvas* canvas, const DrawData& drawData) override;
|
||||
virtual void switch_tool(DrawingProgramToolType newTool) override;
|
||||
virtual bool prevent_undo_or_redo() override;
|
||||
virtual Vector4f* color_picker_color(Vector4f* oldColor) override;
|
||||
virtual void input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button) override;
|
||||
private:
|
||||
CanvasComponentContainer::ObjInfo* objInfoBeingEdited = nullptr;
|
||||
};
|
||||
|
|
@ -25,30 +25,11 @@
|
|||
#include "Helpers/SCollision.hpp"
|
||||
#include "../../CoordSpaceHelper.hpp"
|
||||
#include <ranges>
|
||||
#include <earcut.hpp>
|
||||
#include <include/core/SkPathBuilder.h>
|
||||
#include "../../EarcutIncludes.hpp"
|
||||
|
||||
#include "../../GUIStuff/ElementHelpers/TextLabelHelpers.hpp"
|
||||
|
||||
namespace mapbox {
|
||||
namespace util {
|
||||
|
||||
template <>
|
||||
struct nth<0, Vector2f> {
|
||||
inline static auto get(const Vector2f &t) {
|
||||
return t.x();
|
||||
};
|
||||
};
|
||||
template <>
|
||||
struct nth<1, Vector2f> {
|
||||
inline static auto get(const Vector2f &t) {
|
||||
return t.y();
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace util
|
||||
} // namespace mapbox
|
||||
|
||||
LassoSelectTool::LassoSelectTool(DrawingProgram& initDrawP):
|
||||
DrawingProgramToolBase(initDrawP)
|
||||
{}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@
|
|||
#include "../../MainProgram.hpp"
|
||||
#include "../../DrawData.hpp"
|
||||
#include "DrawingProgramToolBase.hpp"
|
||||
#include "../../CanvasComponents/BrushStrokeCanvasComponent.hpp"
|
||||
#include "../../CanvasComponents/CanvasComponentContainer.hpp"
|
||||
#include "Helpers/MathExtras.hpp"
|
||||
|
||||
|
|
@ -63,26 +62,26 @@ void LineDrawTool::input_mouse_button_on_canvas_callback(const InputManager::Mou
|
|||
if(button.button == InputManager::MouseButton::LEFT) {
|
||||
auto& toolConfig = drawP.world.main.toolConfig;
|
||||
if(button.down && drawP.layerMan.is_a_layer_being_edited() && !objInfoBeingEdited && !drawP.world.main.g.gui.cursor_obstructed()) {
|
||||
auto relativeWidthResult = drawP.world.main.toolConfig.get_relative_width_stroke_size(drawP, drawP.world.drawData.cam.c.inverseScale);
|
||||
if(!relativeWidthResult.first.has_value()) {
|
||||
drawP.world.main.toolConfig.print_relative_width_fail_message(relativeWidthResult.second);
|
||||
return;
|
||||
}
|
||||
float width = relativeWidthResult.first.value();
|
||||
//auto relativeWidthResult = drawP.world.main.toolConfig.get_relative_width_stroke_size(drawP, drawP.world.drawData.cam.c.inverseScale);
|
||||
//if(!relativeWidthResult.first.has_value()) {
|
||||
// drawP.world.main.toolConfig.print_relative_width_fail_message(relativeWidthResult.second);
|
||||
// return;
|
||||
//}
|
||||
//float width = relativeWidthResult.first.value();
|
||||
|
||||
CanvasComponentContainer* newBrushStrokeContainer = new CanvasComponentContainer(drawP.world.netObjMan, CanvasComponentType::BRUSHSTROKE);
|
||||
BrushStrokeCanvasComponent& newBrushStroke = static_cast<BrushStrokeCanvasComponent&>(newBrushStrokeContainer->get_comp());
|
||||
//CanvasComponentContainer* newBrushStrokeContainer = new CanvasComponentContainer(drawP.world.netObjMan, CanvasComponentType::BRUSHSTROKE);
|
||||
//BrushStrokeCanvasComponent& newBrushStroke = static_cast<BrushStrokeCanvasComponent&>(newBrushStrokeContainer->get_comp());
|
||||
|
||||
BrushStrokeCanvasComponentPoint p;
|
||||
p.pos = drawP.world.main.input.mouse.pos;
|
||||
p.width = width;
|
||||
newBrushStroke.d.points->emplace_back(p);
|
||||
p.pos = ensure_points_have_distance(p.pos, p.pos, 1.0f);
|
||||
newBrushStroke.d.points->emplace_back(p);
|
||||
newBrushStroke.d.color = toolConfig.globalConf.foregroundColor;
|
||||
newBrushStroke.d.hasRoundCaps = toolConfig.lineDraw.hasRoundCaps;
|
||||
newBrushStrokeContainer->coords = drawP.world.drawData.cam.c;
|
||||
objInfoBeingEdited = drawP.layerMan.add_component_to_layer_being_edited(newBrushStrokeContainer);
|
||||
//BrushStrokeCanvasComponentPoint p;
|
||||
//p.pos = drawP.world.main.input.mouse.pos;
|
||||
//p.width = width;
|
||||
//newBrushStroke.d.points->emplace_back(p);
|
||||
//p.pos = ensure_points_have_distance(p.pos, p.pos, 1.0f);
|
||||
//newBrushStroke.d.points->emplace_back(p);
|
||||
//newBrushStroke.d.color = toolConfig.globalConf.foregroundColor;
|
||||
//newBrushStroke.d.hasRoundCaps = toolConfig.lineDraw.hasRoundCaps;
|
||||
//newBrushStrokeContainer->coords = drawP.world.drawData.cam.c;
|
||||
//objInfoBeingEdited = drawP.layerMan.add_component_to_layer_being_edited(newBrushStrokeContainer);
|
||||
}
|
||||
else if(!button.down && objInfoBeingEdited)
|
||||
commit();
|
||||
|
|
@ -91,22 +90,22 @@ void LineDrawTool::input_mouse_button_on_canvas_callback(const InputManager::Mou
|
|||
|
||||
void LineDrawTool::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) {
|
||||
if(objInfoBeingEdited) {
|
||||
constexpr float SNAP_DIVISION_COUNT = 12.0f;
|
||||
NetworkingObjects::NetObjOwnerPtr<CanvasComponentContainer>& containerPtr = objInfoBeingEdited->obj;
|
||||
BrushStrokeCanvasComponent& brushStroke = static_cast<BrushStrokeCanvasComponent&>(containerPtr->get_comp());
|
||||
Vector2f newPos = containerPtr->coords.from_cam_space_to_this(drawP.world, motion.pos);
|
||||
Vector2f oldPos = brushStroke.d.points->front().pos;
|
||||
if(drawP.world.main.input.key(InputManager::KEY_GENERIC_LSHIFT).held) {
|
||||
Vector2f diff = (newPos - oldPos);
|
||||
float diffLength = diff.norm();
|
||||
diff.normalize();
|
||||
float angle = (std::atan2(diff.y(), diff.x()) / std::numbers::pi) * SNAP_DIVISION_COUNT;
|
||||
angle = std::round(angle);
|
||||
angle = (angle * std::numbers::pi) / SNAP_DIVISION_COUNT;
|
||||
newPos = oldPos + diffLength * Vector2f{cos(angle), sin(angle)};
|
||||
}
|
||||
brushStroke.d.points->back().pos = ensure_points_have_distance(oldPos, newPos, 1.0f);
|
||||
commitUpdate = true;
|
||||
//constexpr float SNAP_DIVISION_COUNT = 12.0f;
|
||||
//NetworkingObjects::NetObjOwnerPtr<CanvasComponentContainer>& containerPtr = objInfoBeingEdited->obj;
|
||||
//BrushStrokeCanvasComponent& brushStroke = static_cast<BrushStrokeCanvasComponent&>(containerPtr->get_comp());
|
||||
//Vector2f newPos = containerPtr->coords.from_cam_space_to_this(drawP.world, motion.pos);
|
||||
//Vector2f oldPos = brushStroke.d.points->front().pos;
|
||||
//if(drawP.world.main.input.key(InputManager::KEY_GENERIC_LSHIFT).held) {
|
||||
// Vector2f diff = (newPos - oldPos);
|
||||
// float diffLength = diff.norm();
|
||||
// diff.normalize();
|
||||
// float angle = (std::atan2(diff.y(), diff.x()) / std::numbers::pi) * SNAP_DIVISION_COUNT;
|
||||
// angle = std::round(angle);
|
||||
// angle = (angle * std::numbers::pi) / SNAP_DIVISION_COUNT;
|
||||
// newPos = oldPos + diffLength * Vector2f{cos(angle), sin(angle)};
|
||||
//}
|
||||
//brushStroke.d.points->back().pos = ensure_points_have_distance(oldPos, newPos, 1.0f);
|
||||
//commitUpdate = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue