diff --git a/src/DrawingProgram/Tools/ScreenshotTool.cpp b/src/DrawingProgram/Tools/ScreenshotTool.cpp index bc886b1..9429d12 100644 --- a/src/DrawingProgram/Tools/ScreenshotTool.cpp +++ b/src/DrawingProgram/Tools/ScreenshotTool.cpp @@ -53,11 +53,11 @@ void ScreenshotTool::gui_toolbox() { t.gui.push_id("screenshot tool"); t.gui.text_label_centered("Screenshot"); auto oldImgSize = controls.imageSize; - if(controls.selectionMode == 0) + if(controls.selectionMode == ScreenshotControls::SelectionMode::NO_SELECTION) t.gui.text_label("Select an area on the canvas..."); - if(controls.selectionMode != 0 && screenshotConfig.selectedType != SCREENSHOT_SVG) + if(controls.selectionMode != ScreenshotControls::SelectionMode::NO_SELECTION && screenshotConfig.selectedType != SCREENSHOT_SVG) t.gui.input_scalar_fields("Image Size", "Image Size", &controls.imageSize, 2, 0, 999999999); - if(controls.selectionMode == 2) { + if(controls.selectionMode == ScreenshotControls::SelectionMode::SELECTION_EXISTS) { t.gui.left_to_right_line_layout([&]() { t.gui.text_label("Image Type"); t.gui.dropdown_select("image type select", (size_t*)(&screenshotConfig.selectedType), controls.typeSelections); @@ -79,7 +79,7 @@ void ScreenshotTool::gui_toolbox() { controls.imageSize.x() = controls.imageSize.y() * (controls.rectX2 - controls.rectX1) / (controls.rectY2 - controls.rectY1); } if(t.gui.text_button_wide("Take Screenshot", "Take Screenshot")) { - controls.selectionMode = 0; + controls.selectionMode = ScreenshotControls::SelectionMode::NO_SELECTION; #ifdef __EMSCRIPTEN__ take_screenshot("a" + controls.typeSelections[screenshotConfig.selectedType]); #else @@ -119,6 +119,165 @@ bool ScreenshotTool::right_click_popup_gui(Vector2f popupPos) { return true; } +void ScreenshotTool::input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button) { + if(button.button == InputManager::MouseButton::LEFT) { + switch(controls.selectionMode) { + case ScreenshotControls::SelectionMode::NO_SELECTION: { + if(button.down) { + controls.rectX1 = controls.rectX2 = button.pos.x(); + controls.rectY1 = controls.rectY2 = button.pos.y(); + controls.coords = drawP.world.drawData.cam.c; + controls.dragType = 0; + controls.selectionMode = ScreenshotControls::SelectionMode::DRAGGING_BORDER; + } + break; + } + case ScreenshotControls::SelectionMode::DRAGGING_BORDER: { + if(!button.down && dragging_border_update(button.pos)) { + controls.selectionMode = ScreenshotControls::SelectionMode::SELECTION_EXISTS; + commit_rect(); + } + break; + } + case ScreenshotControls::SelectionMode::SELECTION_EXISTS: { + if(button.down && selection_exists_update()) { + for(int i = 0; i < 8; i++) + if(SCollision::collide(controls.circles[i], drawP.world.main.input.mouse.pos)) + controls.dragType = i; + + if(controls.dragType == -1) { + Vector2f mousePosScreenshotCoords = controls.coords.from_cam_space_to_this(drawP.world, button.pos); + if(SCollision::collide(mousePosScreenshotCoords, SCollision::AABB({controls.rectX1, controls.rectY1}, {controls.rectX2, controls.rectY2}))) + controls.dragType = -2; + } + + if(controls.dragType == -1) + controls.selectionMode = ScreenshotControls::SelectionMode::NO_SELECTION; + else if(controls.dragType == -2) { + controls.translateBeginPos = drawP.world.drawData.cam.c.from_space(button.pos); + controls.translateBeginCoords = controls.coords; + controls.selectionMode = ScreenshotControls::SelectionMode::DRAGGING_AREA; + } + else + controls.selectionMode = ScreenshotControls::SelectionMode::DRAGGING_BORDER; + } + break; + } + case ScreenshotControls::SelectionMode::DRAGGING_AREA: { + if(!button.down && dragging_border_update(button.pos)) { + controls.selectionMode = ScreenshotControls::SelectionMode::SELECTION_EXISTS; + commit_rect(); + } + break; + } + } + } +} + +void ScreenshotTool::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) { + switch(controls.selectionMode) { + case ScreenshotControls::SelectionMode::NO_SELECTION: { + break; + } + case ScreenshotControls::SelectionMode::DRAGGING_BORDER: { + dragging_border_update(motion.pos); + break; + } + case ScreenshotControls::SelectionMode::SELECTION_EXISTS: { + break; + } + case ScreenshotControls::SelectionMode::DRAGGING_AREA: { + dragging_area_update(motion.pos); + break; + } + } +} + +bool ScreenshotTool::dragging_border_update(const Vector2f& camCursorPos) { + auto& screenshotConfig = drawP.world.main.toolConfig.screenshot; + Vector2f curPos = controls.coords.from_cam_space_to_this(drawP.world, camCursorPos); + float oldX1 = controls.rectX1; + float oldX2 = controls.rectX2; + float oldY1 = controls.rectY1; + float oldY2 = controls.rectY2; + switch(controls.dragType) { + case 0: + controls.rectX2 = curPos.x(); + controls.rectY2 = curPos.y(); + break; + case 1: + controls.rectY2 = curPos.y(); + break; + case 2: + controls.rectX1 = curPos.x(); + controls.rectY2 = curPos.y(); + break; + case 3: + controls.rectX1 = curPos.x(); + break; + case 4: + controls.rectX1 = curPos.x(); + controls.rectY1 = curPos.y(); + break; + case 5: + controls.rectY1 = curPos.y(); + break; + case 6: + controls.rectX2 = curPos.x(); + controls.rectY1 = curPos.y(); + break; + case 7: + controls.rectX2 = curPos.x(); + break; + } + if(std::fabs(controls.rectX1 - controls.rectX2) > 1e10 || std::fabs(controls.rectY1 - controls.rectY2) > 1e10) { // Limit before screenshot tool starts breaking + controls.rectX1 = oldX1; + controls.rectX2 = oldX2; + controls.rectY1 = oldY1; + controls.rectY2 = oldY2; + } + if((drawP.world.drawData.cam.c.inverseScale << 8) < controls.coords.inverseScale || (drawP.world.drawData.cam.c.inverseScale >> 15) > controls.coords.inverseScale) { + controls.selectionMode = ScreenshotControls::SelectionMode::NO_SELECTION; + return false; + } + + float tempX1 = std::min(controls.rectX1, controls.rectX2); + float tempX2 = std::max(controls.rectX1, controls.rectX2); + float tempY1 = std::min(controls.rectY1, controls.rectY2); + float tempY2 = std::max(controls.rectY1, controls.rectY2); + if(screenshotConfig.setDimensionIsX) { + controls.imageSize.x() = screenshotConfig.setDimensionSize; + controls.imageSize.y() = controls.imageSize.x() * (tempY2 - tempY1) / (tempX2 - tempX1); + } + else { + controls.imageSize.y() = screenshotConfig.setDimensionSize; + controls.imageSize.x() = controls.imageSize.y() * (tempX2 - tempX1) / (tempY2 - tempY1); + } + + return true; +} + +bool ScreenshotTool::selection_exists_update() { + commit_rect(); + controls.dragType = -1; + + if((drawP.world.drawData.cam.c.inverseScale << 8) < controls.coords.inverseScale || (drawP.world.drawData.cam.c.inverseScale >> 15) > controls.coords.inverseScale) { + controls.selectionMode = ScreenshotControls::SelectionMode::NO_SELECTION; + return false; + } + return true; +} + +bool ScreenshotTool::dragging_area_update(const Vector2f& camCursorPos) { + controls.coords = controls.translateBeginCoords; + controls.coords.translate(drawP.world.drawData.cam.c.from_space(camCursorPos) - controls.translateBeginPos); + if((drawP.world.drawData.cam.c.inverseScale << 8) < controls.coords.inverseScale || (drawP.world.drawData.cam.c.inverseScale >> 15) > controls.coords.inverseScale) { + controls.selectionMode = ScreenshotControls::SelectionMode::NO_SELECTION; + return false; + } + return true; +} + void ScreenshotTool::erase_component(CanvasComponentContainer::ObjInfo* erasedComp) { } @@ -302,138 +461,16 @@ void ScreenshotTool::take_screenshot_area_hw(const sk_sp& surface, Sk } void ScreenshotTool::switch_tool(DrawingProgramToolType newTool) { - controls.selectionMode = 0; + controls.selectionMode = ScreenshotControls::SelectionMode::NO_SELECTION; } void ScreenshotTool::tool_update() { - auto& screenshotConfig = drawP.world.main.toolConfig.screenshot; if(controls.setToTakeScreenshot) { controls.setToTakeScreenshot = false; take_screenshot(controls.screenshotSavePath); } - switch(controls.selectionMode) { - case 0: { - if(drawP.controls.leftClick) { - controls.rectX1 = controls.rectX2 = drawP.world.main.input.mouse.pos.x(); - controls.rectY1 = controls.rectY2 = drawP.world.main.input.mouse.pos.y(); - controls.coords = drawP.world.drawData.cam.c; - controls.dragType = 0; - controls.selectionMode = 1; - } - break; - } - case 1: { - Vector2f curPos = controls.coords.get_mouse_pos(drawP.world); - float oldX1 = controls.rectX1; - float oldX2 = controls.rectX2; - float oldY1 = controls.rectY1; - float oldY2 = controls.rectY2; - switch(controls.dragType) { - case 0: - controls.rectX2 = curPos.x(); - controls.rectY2 = curPos.y(); - break; - case 1: - controls.rectY2 = curPos.y(); - break; - case 2: - controls.rectX1 = curPos.x(); - controls.rectY2 = curPos.y(); - break; - case 3: - controls.rectX1 = curPos.x(); - break; - case 4: - controls.rectX1 = curPos.x(); - controls.rectY1 = curPos.y(); - break; - case 5: - controls.rectY1 = curPos.y(); - break; - case 6: - controls.rectX2 = curPos.x(); - controls.rectY1 = curPos.y(); - break; - case 7: - controls.rectX2 = curPos.x(); - break; - } - if(std::fabs(controls.rectX1 - controls.rectX2) > 1e10 || std::fabs(controls.rectY1 - controls.rectY2) > 1e10) { // Limit before screenshot tool starts breaking - controls.rectX1 = oldX1; - controls.rectX2 = oldX2; - controls.rectY1 = oldY1; - controls.rectY2 = oldY2; - } - if((drawP.world.drawData.cam.c.inverseScale << 8) < controls.coords.inverseScale || (drawP.world.drawData.cam.c.inverseScale >> 15) > controls.coords.inverseScale) { - controls.selectionMode = 0; - break; - } - - float tempX1 = std::min(controls.rectX1, controls.rectX2); - float tempX2 = std::max(controls.rectX1, controls.rectX2); - float tempY1 = std::min(controls.rectY1, controls.rectY2); - float tempY2 = std::max(controls.rectY1, controls.rectY2); - if(screenshotConfig.setDimensionIsX) { - controls.imageSize.x() = screenshotConfig.setDimensionSize; - controls.imageSize.y() = controls.imageSize.x() * (tempY2 - tempY1) / (tempX2 - tempX1); - } - else { - controls.imageSize.y() = screenshotConfig.setDimensionSize; - controls.imageSize.x() = controls.imageSize.y() * (tempX2 - tempX1) / (tempY2 - tempY1); - } - - if(!drawP.controls.leftClickHeld) { - controls.selectionMode = 2; - commit_rect(); - } - break; - } - case 2: { - commit_rect(); - controls.dragType = -1; - - if((drawP.world.drawData.cam.c.inverseScale << 8) < controls.coords.inverseScale || (drawP.world.drawData.cam.c.inverseScale >> 15) > controls.coords.inverseScale) { - controls.selectionMode = 0; - break; - } - - if(drawP.controls.cursorHoveringOverCanvas && drawP.controls.leftClick) { - for(int i = 0; i < 8; i++) - if(SCollision::collide(controls.circles[i], drawP.world.main.input.mouse.pos)) - controls.dragType = i; - - if(controls.dragType == -1) { - Vector2f mousePosScreenshotCoords = controls.coords.get_mouse_pos(drawP.world); - if(SCollision::collide(mousePosScreenshotCoords, SCollision::AABB({controls.rectX1, controls.rectY1}, {controls.rectX2, controls.rectY2}))) - controls.dragType = -2; - } - - if(controls.dragType == -1) - controls.selectionMode = 0; - else if(controls.dragType == -2) { - controls.translateBeginPos = drawP.world.get_mouse_world_pos(); - controls.translateBeginCoords = controls.coords; - controls.selectionMode = 3; - } - else - controls.selectionMode = 1; - } - break; - } - case 3: { - controls.coords = controls.translateBeginCoords; - controls.coords.translate(drawP.world.get_mouse_world_pos() - controls.translateBeginPos); - if((drawP.world.drawData.cam.c.inverseScale << 8) < controls.coords.inverseScale || (drawP.world.drawData.cam.c.inverseScale >> 15) > controls.coords.inverseScale) { - controls.selectionMode = 0; - break; - } - if(!drawP.controls.leftClickHeld) { - controls.selectionMode = 2; - commit_rect(); - } - break; - } - } + if(controls.selectionMode == ScreenshotControls::SelectionMode::SELECTION_EXISTS) + selection_exists_update(); } void ScreenshotTool::commit_rect() { @@ -461,7 +498,7 @@ bool ScreenshotTool::prevent_undo_or_redo() { } void ScreenshotTool::draw(SkCanvas* canvas, const DrawData& drawData) { - if(controls.selectionMode == 0) { + if(controls.selectionMode == ScreenshotControls::SelectionMode::NO_SELECTION) { SkPaint paint1; paint1.setColor4f({0.0f, 0.0f, 0.0f, 0.3f}); canvas->drawPaint(paint1); @@ -491,7 +528,7 @@ void ScreenshotTool::draw(SkCanvas* canvas, const DrawData& drawData) { canvas->restore(); - if(controls.selectionMode == 2) { + if(controls.selectionMode == ScreenshotControls::SelectionMode::SELECTION_EXISTS) { paint2.setStyle(SkPaint::kFill_Style); for(auto& circ : controls.circles) drawP.draw_drag_circle(canvas, circ.pos, {0.1f, 0.9f, 0.9f, 1.0f}, drawData, 1.0f); diff --git a/src/DrawingProgram/Tools/ScreenshotTool.hpp b/src/DrawingProgram/Tools/ScreenshotTool.hpp index 7447038..b561ad7 100644 --- a/src/DrawingProgram/Tools/ScreenshotTool.hpp +++ b/src/DrawingProgram/Tools/ScreenshotTool.hpp @@ -18,6 +18,8 @@ class ScreenshotTool : public DrawingProgramToolBase { virtual void draw(SkCanvas* canvas, const DrawData& drawData) override; virtual void switch_tool(DrawingProgramToolType newTool) override; virtual bool prevent_undo_or_redo() override; + virtual void input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button) override; + virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) override; enum ScreenshotType : size_t { SCREENSHOT_JPG, @@ -31,17 +33,6 @@ class ScreenshotTool : public DrawingProgramToolBase { void take_screenshot_area_hw(const sk_sp& surface, SkCanvas* canvas, void* fullImgRawData, const Vector2i& fullImageSize, const Vector2i& sectionImagePos, const Vector2i& sectionImageSize, const Vector2i& canvasSize, bool transparentBackground); void take_screenshot_svg(SkCanvas* canvas, bool transparentBackground); - //static constexpr std::array cursors{ - // InputManager::SystemCursorType::SE_RESIZE, - // InputManager::SystemCursorType::S_RESIZE, - // InputManager::SystemCursorType::SW_RESIZE, - // InputManager::SystemCursorType::W_RESIZE, - // InputManager::SystemCursorType::NW_RESIZE, - // InputManager::SystemCursorType::N_RESIZE, - // InputManager::SystemCursorType::NE_RESIZE, - // InputManager::SystemCursorType::E_RESIZE - //}; - struct ScreenshotControls { CoordSpaceHelper translateBeginCoords; WorldVec translateBeginPos; @@ -51,7 +42,12 @@ class ScreenshotTool : public DrawingProgramToolBase { float rectX2; float rectY1; float rectY2; - int selectionMode = 0; + enum class SelectionMode { + NO_SELECTION, + DRAGGING_BORDER, + SELECTION_EXISTS, + DRAGGING_AREA + } selectionMode; int dragType = 0; Vector2i imageSize = {0, 0}; std::array, 8> circles; @@ -64,6 +60,9 @@ class ScreenshotTool : public DrawingProgramToolBase { std::atomic setToTakeScreenshot = false; std::filesystem::path screenshotSavePath; } controls; + bool dragging_border_update(const Vector2f& camCursorPos); + bool selection_exists_update(); + bool dragging_area_update(const Vector2f& camCursorPos); }; NLOHMANN_JSON_SERIALIZE_ENUM(ScreenshotTool::ScreenshotType, {