diff --git a/include/Helpers/CallbackManager.hpp b/include/Helpers/CallbackManager.hpp index cadb86e..bd93c2e 100644 --- a/include/Helpers/CallbackManager.hpp +++ b/include/Helpers/CallbackManager.hpp @@ -18,9 +18,13 @@ template class CallbackManager { for(auto& f : funcs) (*f)(a...); } - ~CallbackManager() { + void clear() { for(Callback* c : funcs) delete c; + funcs.clear(); + } + ~CallbackManager() { + clear(); } private: std::vector funcs; diff --git a/src/DrawingProgram/DrawingProgram.cpp b/src/DrawingProgram/DrawingProgram.cpp index bb984e7..dae6d2d 100644 --- a/src/DrawingProgram/DrawingProgram.cpp +++ b/src/DrawingProgram/DrawingProgram.cpp @@ -45,102 +45,131 @@ DrawingProgram::DrawingProgram(World& initWorld): drawTool = DrawingProgramToolBase::allocate_tool_type(*this, DrawingProgramToolType::BRUSH); } -void DrawingProgram::register_callbacks() { - world.keyCallbacks[InputManager::KEY_DRAW_TOOL_BRUSH] = world.main.input.keyCallbacks[InputManager::KEY_DRAW_TOOL_BRUSH].register_callback([&](auto& key) { - if(key.down && !key.repeat) - switch_to_tool(DrawingProgramToolType::BRUSH); - }); - world.keyCallbacks[InputManager::KEY_DRAW_TOOL_ERASER] = world.main.input.keyCallbacks[InputManager::KEY_DRAW_TOOL_ERASER].register_callback([&](auto& key) { - if(key.down && !key.repeat) - switch_to_tool(DrawingProgramToolType::ERASER); - }); - world.keyCallbacks[InputManager::KEY_DRAW_TOOL_RECTSELECT] = world.main.input.keyCallbacks[InputManager::KEY_DRAW_TOOL_RECTSELECT].register_callback([&](auto& key) { - if(key.down && !key.repeat) - switch_to_tool(DrawingProgramToolType::RECTSELECT); - }); - world.keyCallbacks[InputManager::KEY_DRAW_TOOL_RECTANGLE] = world.main.input.keyCallbacks[InputManager::KEY_DRAW_TOOL_RECTANGLE].register_callback([&](auto& key) { - if(key.down && !key.repeat) - switch_to_tool(DrawingProgramToolType::RECTANGLE); - }); - world.keyCallbacks[InputManager::KEY_DRAW_TOOL_ELLIPSE] = world.main.input.keyCallbacks[InputManager::KEY_DRAW_TOOL_ELLIPSE].register_callback([&](auto& key) { - if(key.down && !key.repeat) - switch_to_tool(DrawingProgramToolType::ELLIPSE); - }); - world.keyCallbacks[InputManager::KEY_DRAW_TOOL_TEXTBOX] = world.main.input.keyCallbacks[InputManager::KEY_DRAW_TOOL_TEXTBOX].register_callback([&](auto& key) { - if(key.down && !key.repeat) - switch_to_tool(DrawingProgramToolType::TEXTBOX); - }); - world.keyCallbacks[InputManager::KEY_DRAW_TOOL_EYEDROPPER] = world.main.input.keyCallbacks[InputManager::KEY_DRAW_TOOL_EYEDROPPER].register_callback([&](auto& key) { - if(key.down && !key.repeat) - switch_to_tool(DrawingProgramToolType::EYEDROPPER); - }); - world.keyCallbacks[InputManager::KEY_DRAW_TOOL_SCREENSHOT] = world.main.input.keyCallbacks[InputManager::KEY_DRAW_TOOL_SCREENSHOT].register_callback([&](auto& key) { - if(key.down && !key.repeat) - switch_to_tool(DrawingProgramToolType::SCREENSHOT); - }); - world.keyCallbacks[InputManager::KEY_DRAW_TOOL_ZOOM] = world.main.input.keyCallbacks[InputManager::KEY_DRAW_TOOL_ZOOM].register_callback([&](auto& key) { - if(key.down && !key.repeat) - switch_to_tool(DrawingProgramToolType::ZOOM); - }); - world.keyCallbacks[InputManager::KEY_DRAW_TOOL_LASSOSELECT] = world.main.input.keyCallbacks[InputManager::KEY_DRAW_TOOL_LASSOSELECT].register_callback([&](auto& key) { - if(key.down && !key.repeat) - switch_to_tool(DrawingProgramToolType::LASSOSELECT); - }); - world.keyCallbacks[InputManager::KEY_DRAW_TOOL_PAN] = world.main.input.keyCallbacks[InputManager::KEY_DRAW_TOOL_PAN].register_callback([&](auto& key) { - if(key.down && !key.repeat) - switch_to_tool(DrawingProgramToolType::PAN); - }); - world.keyCallbacks[InputManager::KEY_DRAW_TOOL_LINE] = world.main.input.keyCallbacks[InputManager::KEY_DRAW_TOOL_LINE].register_callback([&](auto& key) { - if(key.down && !key.repeat) - switch_to_tool(DrawingProgramToolType::LINE); - }); - world.keyCallbacks[InputManager::KEY_HOLD_TO_PAN] = world.main.input.keyCallbacks[InputManager::KEY_HOLD_TO_PAN].register_callback([&](auto& key) { - if(key.down && !key.repeat && tempMoveToolSwitch == TemporaryMoveToolSwitch::NONE) { - toolTypeAfterTempMove = drawTool->get_type(); - switch_to_tool(DrawingProgramToolType::PAN); - tempMoveToolSwitch = TemporaryMoveToolSwitch::PAN; - } - else if(!key.down && tempMoveToolSwitch == TemporaryMoveToolSwitch::PAN) { - switch_to_tool(toolTypeAfterTempMove); - tempMoveToolSwitch = TemporaryMoveToolSwitch::NONE; - } - }); - world.keyCallbacks[InputManager::KEY_HOLD_TO_ZOOM] = world.main.input.keyCallbacks[InputManager::KEY_HOLD_TO_ZOOM].register_callback([&](auto& key) { - if(key.down && !key.repeat && tempMoveToolSwitch == TemporaryMoveToolSwitch::NONE) { - toolTypeAfterTempMove = drawTool->get_type(); - switch_to_tool(DrawingProgramToolType::ZOOM); - tempMoveToolSwitch = TemporaryMoveToolSwitch::ZOOM; - } - else if(!key.down && tempMoveToolSwitch == TemporaryMoveToolSwitch::ZOOM) { - switch_to_tool(toolTypeAfterTempMove); - tempMoveToolSwitch = TemporaryMoveToolSwitch::NONE; - } - }); - mouseButtonCallback = world.main.input.mouseButtonCallbacks.register_callback([&](const InputManager::MouseButtonCallbackArgs& button) { - bool isHoveringOverCanvas = world.main.toolbar.check_if_position_isnt_obstructed(button.pos); - if(isHoveringOverCanvas) { - if(button.button == InputManager::MouseButtonCallbackArgs::Button::RIGHT) { - if(button.down) { - if(world.main.toolbar.rightClickPopupLocation) - world.main.toolbar.rightClickPopupLocation = std::nullopt; - else - world.main.toolbar.rightClickPopupLocation = world.main.input.mouse.pos / world.main.toolbar.final_gui_scale(); - } - } - else { - if(button.down) - world.main.toolbar.rightClickPopupLocation = std::nullopt; - mouseButtonOnCanvasCallbacks.run_callbacks(button); - } - } - }); - selection.register_callbacks(); +void DrawingProgram::on_tab_out() { + tempMoveToolSwitch = TemporaryMoveToolSwitch::NONE; + selection.deselect_all(); + controls.leftClickHeld = false; + controls.middleClickHeld = false; } -void DrawingProgram::deregister_callbacks() { - tempMoveToolSwitch = TemporaryMoveToolSwitch::NONE; - world.main.input.mouseButtonCallbacks.deregister_callback(mouseButtonCallback); - selection.deselect_all(); +void DrawingProgram::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) { + bool isHoveringOverCanvas = world.main.toolbar.check_if_position_isnt_obstructed(button.pos); + if(isHoveringOverCanvas) { + if(button.button == InputManager::MouseButtonCallbackArgs::Button::RIGHT) { + if(button.down) { + if(world.main.toolbar.rightClickPopupLocation) + world.main.toolbar.rightClickPopupLocation = std::nullopt; + else + world.main.toolbar.rightClickPopupLocation = world.main.input.mouse.pos / world.main.toolbar.final_gui_scale(); + } + } + else { + if(button.down) + world.main.toolbar.rightClickPopupLocation = std::nullopt; + if(button.button == InputManager::MouseButtonCallbackArgs::Button::LEFT) + controls.leftClickHeld = button.down; + else if(button.button == InputManager::MouseButtonCallbackArgs::Button::MIDDLE) + controls.middleClickHeld = button.down; + drawTool->input_mouse_button_on_canvas_callback(button); + } + } + else if(!button.down && button.button != InputManager::MouseButtonCallbackArgs::Button::RIGHT) { + drawTool->input_mouse_button_on_canvas_callback(button); + } +} + +void DrawingProgram::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) { + drawTool->input_mouse_motion_callback(motion); +} + +void DrawingProgram::input_key_callback(const InputManager::KeyCallbackArgs& key) { + switch(key.key) { + case InputManager::KEY_DRAW_TOOL_BRUSH: { + if(key.down && !key.repeat) + switch_to_tool(DrawingProgramToolType::BRUSH); + break; + } + case InputManager::KEY_DRAW_TOOL_ERASER: { + if(key.down && !key.repeat) + switch_to_tool(DrawingProgramToolType::ERASER); + break; + } + case InputManager::KEY_DRAW_TOOL_RECTSELECT: { + if(key.down && !key.repeat) + switch_to_tool(DrawingProgramToolType::RECTSELECT); + break; + } + case InputManager::KEY_DRAW_TOOL_RECTANGLE: { + if(key.down && !key.repeat) + switch_to_tool(DrawingProgramToolType::RECTANGLE); + break; + } + case InputManager::KEY_DRAW_TOOL_ELLIPSE: { + if(key.down && !key.repeat) + switch_to_tool(DrawingProgramToolType::ELLIPSE); + break; + } + case InputManager::KEY_DRAW_TOOL_TEXTBOX: { + if(key.down && !key.repeat) + switch_to_tool(DrawingProgramToolType::TEXTBOX); + break; + } + case InputManager::KEY_DRAW_TOOL_EYEDROPPER: { + if(key.down && !key.repeat) + switch_to_tool(DrawingProgramToolType::EYEDROPPER); + break; + } + case InputManager::KEY_DRAW_TOOL_SCREENSHOT: { + if(key.down && !key.repeat) + switch_to_tool(DrawingProgramToolType::SCREENSHOT); + break; + } + case InputManager::KEY_DRAW_TOOL_ZOOM: { + if(key.down && !key.repeat) + switch_to_tool(DrawingProgramToolType::ZOOM); + break; + } + case InputManager::KEY_DRAW_TOOL_LASSOSELECT: { + if(key.down && !key.repeat) + switch_to_tool(DrawingProgramToolType::LASSOSELECT); + break; + } + case InputManager::KEY_DRAW_TOOL_PAN: { + if(key.down && !key.repeat) + switch_to_tool(DrawingProgramToolType::PAN); + break; + } + case InputManager::KEY_DRAW_TOOL_LINE: { + if(key.down && !key.repeat) + switch_to_tool(DrawingProgramToolType::LINE); + break; + } + case InputManager::KEY_HOLD_TO_PAN: { + if(key.down && !key.repeat && tempMoveToolSwitch == TemporaryMoveToolSwitch::NONE) { + toolTypeAfterTempMove = drawTool->get_type(); + switch_to_tool(DrawingProgramToolType::PAN); + tempMoveToolSwitch = TemporaryMoveToolSwitch::PAN; + } + else if(!key.down && tempMoveToolSwitch == TemporaryMoveToolSwitch::PAN) { + switch_to_tool(toolTypeAfterTempMove); + tempMoveToolSwitch = TemporaryMoveToolSwitch::NONE; + } + break; + } + case InputManager::KEY_HOLD_TO_ZOOM: { + if(key.down && !key.repeat && tempMoveToolSwitch == TemporaryMoveToolSwitch::NONE) { + toolTypeAfterTempMove = drawTool->get_type(); + switch_to_tool(DrawingProgramToolType::ZOOM); + tempMoveToolSwitch = TemporaryMoveToolSwitch::ZOOM; + } + else if(!key.down && tempMoveToolSwitch == TemporaryMoveToolSwitch::ZOOM) { + switch_to_tool(toolTypeAfterTempMove); + tempMoveToolSwitch = TemporaryMoveToolSwitch::NONE; + } + break; + } + } + drawTool->input_key_callback(key); } void DrawingProgram::server_init_no_file() { @@ -341,26 +370,6 @@ void DrawingProgram::update() { controls.cursorHoveringOverCanvas = world.main.toolbar.check_if_position_isnt_obstructed(world.main.input.mouse.pos); - controls.middleClick = controls.cursorHoveringOverCanvas && (world.main.input.mouse.middleClicks || world.main.input.pen.buttons[world.main.toolbar.tabletOptions.middleClickButton].pressed); - bool middleHeld = world.main.input.mouse.middleDown || world.main.input.pen.buttons[world.main.toolbar.tabletOptions.middleClickButton].held; - if(controls.middleClick) - controls.middleClickHeld = true; - if(controls.middleClickHeld && !middleHeld) { - controls.middleClick = false; - controls.middleClickHeld = false; - controls.middleClickReleased = true; - } - - // Left click will be ignored if middle click is held (and left click held state will be gone once middle click is pressed) - controls.leftClick = controls.cursorHoveringOverCanvas && world.main.input.mouse.leftClicks && !controls.middleClickHeld; - if(controls.leftClick) - controls.leftClickHeld = true; - if(controls.leftClickHeld && (!world.main.input.mouse.leftDown || controls.middleClickHeld)) { - controls.leftClick = false; - controls.leftClickHeld = false; - controls.leftClickReleased = true; - } - controls.previousMouseWorldPos = controls.currentMouseWorldPos; controls.currentMouseWorldPos = world.get_mouse_world_pos(); diff --git a/src/DrawingProgram/DrawingProgram.hpp b/src/DrawingProgram/DrawingProgram.hpp index a5ee675..f7f07e2 100644 --- a/src/DrawingProgram/DrawingProgram.hpp +++ b/src/DrawingProgram/DrawingProgram.hpp @@ -57,11 +57,10 @@ class DrawingProgram { void preupdate_component(CanvasComponentContainer::ObjInfo* objToCheck); void send_transforms_for(const std::vector& objsToSendTransformsFor); - void register_callbacks(); - void deregister_callbacks(); - - typedef CallbackManager MouseButtonOnCanvasCallbackManager; - MouseButtonOnCanvasCallbackManager mouseButtonOnCanvasCallbacks; + void on_tab_out(); + void input_key_callback(const InputManager::KeyCallbackArgs& key); + void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button); + void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion); private: void process_transform_message(const std::vector>& transforms); @@ -97,8 +96,6 @@ class DrawingProgram { TemporaryMoveToolSwitch tempMoveToolSwitch = TemporaryMoveToolSwitch::NONE; DrawingProgramToolType toolTypeAfterTempMove; - InputManager::MouseButtonCallbackManager::Callback* mouseButtonCallback; - struct GlobalControls { std::optional lockedCameraScale; diff --git a/src/DrawingProgram/DrawingProgramSelection.cpp b/src/DrawingProgram/DrawingProgramSelection.cpp index 5a27f26..f90c9a6 100644 --- a/src/DrawingProgram/DrawingProgramSelection.cpp +++ b/src/DrawingProgram/DrawingProgramSelection.cpp @@ -352,144 +352,161 @@ void DrawingProgramSelection::commit_transform_selection() { } void DrawingProgramSelection::update() { - if(is_something_selected()) { - rebuild_cam_space(); +} - if(drawP.is_actual_selection_tool(drawP.drawTool->get_type())) { - switch(transformOpHappening) { - case TransformOperation::NONE: - if(drawP.controls.leftClick && !drawP.world.main.input.key(InputManager::KEY_GENERIC_LSHIFT).held && !drawP.world.main.input.key(InputManager::KEY_GENERIC_LALT).held) { - if(mouse_collided_with_scale_point()) { - scaleData.currentPos = scaleData.startPos = selectionTransformCoords.from_space_world(initialSelectionAABB.max); - scaleData.centerPos = selectionTransformCoords.from_space_world(initialSelectionAABB.center()); - transformOpHappening = TransformOperation::SCALE; - check_add_stroke_color_change_undo(); - } - else if(mouse_collided_with_rotate_center_handle_point()) { - transformOpHappening = TransformOperation::ROTATE_RELOCATE_CENTER; - check_add_stroke_color_change_undo(); - } - else if(mouse_collided_with_rotate_handle_point()) { - rotateData.rotationAngle = 0.0; - transformOpHappening = TransformOperation::ROTATE; - check_add_stroke_color_change_undo(); - } - else if(mouse_collided_with_selection_aabb()) { - translateData.startPos = drawP.world.get_mouse_world_pos(); - transformOpHappening = TransformOperation::TRANSLATE; - translateData.translateWithKeys = false; - check_add_stroke_color_change_undo(); - } - } - break; - case TransformOperation::TRANSLATE: - if(!translateData.translateWithKeys) { - if(drawP.controls.leftClickHeld) - selectionTransformCoords = CoordSpaceHelperTransform(drawP.world.get_mouse_world_pos() - translateData.startPos); - else { - commit_transform_selection(); - return; - } - } - break; - case TransformOperation::SCALE: - if(drawP.controls.leftClickHeld) { - WorldVec centerToScaleStart = scaleData.startPos - scaleData.centerPos; - Vector2f centerToScaleStartInCamSpace = drawP.world.drawData.cam.c.normalized_dir_to_space(centerToScaleStart.normalized()); - Vector2f scaleCenterPointInCamSpace = drawP.world.drawData.cam.c.to_space(scaleData.centerPos); - scaleData.currentPos = drawP.world.drawData.cam.c.from_space(project_point_on_line(drawP.world.main.input.mouse.pos, scaleCenterPointInCamSpace, (scaleCenterPointInCamSpace + centerToScaleStartInCamSpace).eval())); - - WorldVec centerToScaleCurrent = scaleData.currentPos - scaleData.centerPos; - - WorldScalar centerToScaleStartNorm = centerToScaleStart.norm(); - WorldScalar centerToScaleCurrentNorm = centerToScaleCurrent.norm(); - bool isAnyNumberZero = centerToScaleCurrentNorm == WorldScalar(0) || centerToScaleStartNorm == WorldScalar(0); - - if(!isAnyNumberZero) { - WorldMultiplier scaleAmount = WorldMultiplier(centerToScaleStartNorm) / WorldMultiplier(centerToScaleCurrentNorm); - - selectionTransformCoords = CoordSpaceHelperTransform(scaleData.centerPos, scaleAmount); - } - } - else { - commit_transform_selection(); - return; - } - break; - case TransformOperation::ROTATE_RELOCATE_CENTER: - if(drawP.controls.leftClickHeld) - rotateData.centerPos = drawP.world.get_mouse_world_pos(); - else - transformOpHappening = TransformOperation::NONE; - break; - case TransformOperation::ROTATE: - if(drawP.controls.leftClickHeld) { - Vector2f rotationPointDiff = drawP.world.main.input.mouse.pos - rotateData.centerHandlePoint; - rotateData.rotationAngle = std::atan2(rotationPointDiff.y(), rotationPointDiff.x()); - selectionTransformCoords = CoordSpaceHelperTransform(rotateData.centerPos, rotateData.rotationAngle); - } - else { - commit_transform_selection(); - return; - } - break; - } +void DrawingProgramSelection::input_key_callback_modify_selection(const InputManager::KeyCallbackArgs& key) { + switch(key.key) { + case InputManager::KEY_TEXT_UP: { + translate_key(InputManager::KEY_TEXT_UP, key.down); + break; } - else if(transformOpHappening != TransformOperation::NONE) { - commit_transform_selection(); - return; + case InputManager::KEY_TEXT_DOWN: { + translate_key(InputManager::KEY_TEXT_DOWN, key.down); + break; + } + case InputManager::KEY_TEXT_LEFT: { + translate_key(InputManager::KEY_TEXT_LEFT, key.down); + break; + } + case InputManager::KEY_TEXT_RIGHT: { + translate_key(InputManager::KEY_TEXT_RIGHT, key.down); + break; } } } -void DrawingProgramSelection::register_callbacks() { - auto& keyCallbacks = drawP.world.keyCallbacks; - keyCallbacks[InputManager::KEY_DRAW_DELETE] = drawP.world.main.input.keyCallbacks[InputManager::KEY_DRAW_DELETE].register_callback([&](auto& key) { - if(key.down && !key.repeat) - delete_all(); - }); - keyCallbacks[InputManager::KEY_COPY] = drawP.world.main.input.keyCallbacks[InputManager::KEY_COPY].register_callback([&](auto& key) { - if(key.down && !key.repeat) - selection_to_clipboard(); - }); - keyCallbacks[InputManager::KEY_CUT] = drawP.world.main.input.keyCallbacks[InputManager::KEY_CUT].register_callback([&](auto& key) { - if(key.down && !key.repeat) { - selection_to_clipboard(); - delete_all(); +void DrawingProgramSelection::input_key_callback_display_selection(const InputManager::KeyCallbackArgs& key) { + switch(key.key) { + case InputManager::KEY_DRAW_DELETE: { + if(key.down && !key.repeat) + delete_all(); + break; } - }); - keyCallbacks[InputManager::KEY_PASTE] = drawP.world.main.input.keyCallbacks[InputManager::KEY_PASTE].register_callback([&](auto& key) { - if(key.down && !key.repeat) { - deselect_all(); - paste_clipboard(drawP.world.main.input.mouse.pos); + case InputManager::KEY_COPY: { + if(key.down && !key.repeat) + selection_to_clipboard(); + break; } - }); - keyCallbacks[InputManager::KEY_PASTE_IMAGE] = drawP.world.main.input.keyCallbacks[InputManager::KEY_PASTE_IMAGE].register_callback([&](auto& key) { - if(key.down && !key.repeat) { - deselect_all(); - paste_image(drawP.world.main.input.mouse.pos); + case InputManager::KEY_CUT: { + if(key.down && !key.repeat) { + selection_to_clipboard(); + delete_all(); + } + break; } - }); - keyCallbacks[InputManager::KEY_DESELECT_AND_EDIT_TOOL] = drawP.world.main.input.keyCallbacks[InputManager::KEY_DESELECT_AND_EDIT_TOOL].register_callback([&](auto& key) { - if(key.down && !key.repeat) { - if(is_something_selected()) + case InputManager::KEY_PASTE: { + if(key.down && !key.repeat) { deselect_all(); - else - drawP.switch_to_tool(DrawingProgramToolType::EDIT, true); + paste_clipboard(drawP.world.main.input.mouse.pos); + } + break; } - }); - keyCallbacks[InputManager::KEY_TEXT_UP] = drawP.world.main.input.keyCallbacks[InputManager::KEY_TEXT_UP].register_callback([&](auto& key) { - translate_key(InputManager::KEY_TEXT_UP, key.down); - }); - keyCallbacks[InputManager::KEY_TEXT_DOWN] = drawP.world.main.input.keyCallbacks[InputManager::KEY_TEXT_DOWN].register_callback([&](auto& key) { - translate_key(InputManager::KEY_TEXT_DOWN, key.down); - }); - keyCallbacks[InputManager::KEY_TEXT_LEFT] = drawP.world.main.input.keyCallbacks[InputManager::KEY_TEXT_LEFT].register_callback([&](auto& key) { - translate_key(InputManager::KEY_TEXT_LEFT, key.down); - }); - keyCallbacks[InputManager::KEY_TEXT_RIGHT] = drawP.world.main.input.keyCallbacks[InputManager::KEY_TEXT_RIGHT].register_callback([&](auto& key) { - translate_key(InputManager::KEY_TEXT_RIGHT, key.down); - }); + case InputManager::KEY_PASTE_IMAGE: { + if(key.down && !key.repeat) { + deselect_all(); + paste_image(drawP.world.main.input.mouse.pos); + } + break; + } + case InputManager::KEY_DESELECT_AND_EDIT_TOOL: { + if(key.down && !key.repeat) { + if(is_something_selected()) + deselect_all(); + else + drawP.switch_to_tool(DrawingProgramToolType::EDIT, true); + } + break; + } + } +} + +void DrawingProgramSelection::input_mouse_button_on_canvas_callback_modify_selection(const InputManager::MouseButtonCallbackArgs& button) { + if(button.button == InputManager::MouseButtonCallbackArgs::Button::LEFT) { + switch(transformOpHappening) { + case TransformOperation::NONE: { + if(button.down && !drawP.world.main.input.key(InputManager::KEY_GENERIC_LSHIFT).held && !drawP.world.main.input.key(InputManager::KEY_GENERIC_LALT).held) { + if(mouse_collided_with_scale_point()) { + scaleData.currentPos = scaleData.startPos = selectionTransformCoords.from_space_world(initialSelectionAABB.max); + scaleData.centerPos = selectionTransformCoords.from_space_world(initialSelectionAABB.center()); + transformOpHappening = TransformOperation::SCALE; + check_add_stroke_color_change_undo(); + } + else if(mouse_collided_with_rotate_center_handle_point()) { + transformOpHappening = TransformOperation::ROTATE_RELOCATE_CENTER; + check_add_stroke_color_change_undo(); + } + else if(mouse_collided_with_rotate_handle_point()) { + rotateData.rotationAngle = 0.0; + transformOpHappening = TransformOperation::ROTATE; + check_add_stroke_color_change_undo(); + } + else if(mouse_collided_with_selection_aabb()) { + translateData.startPos = drawP.world.get_mouse_world_pos(); + transformOpHappening = TransformOperation::TRANSLATE; + translateData.translateWithKeys = false; + check_add_stroke_color_change_undo(); + } + } + break; + } + case TransformOperation::TRANSLATE: + case TransformOperation::ROTATE: + case TransformOperation::SCALE: { + if(!button.down) + commit_transform_selection(); + break; + } + case TransformOperation::ROTATE_RELOCATE_CENTER: { + if(!button.down) + transformOpHappening = TransformOperation::NONE; + break; + } + } + } +} + +void DrawingProgramSelection::input_mouse_motion_callback_modify_selection(const InputManager::MouseMotionCallbackArgs& motion) { + if(drawP.world.main.input.mouse.leftDown) { + rebuild_cam_space(); + + switch(transformOpHappening) { + case TransformOperation::NONE: + break; + case TransformOperation::TRANSLATE: { + if(!translateData.translateWithKeys) + selectionTransformCoords = CoordSpaceHelperTransform(drawP.world.drawData.cam.c.from_space(motion.pos) - translateData.startPos); + break; + } + case TransformOperation::SCALE: { + WorldVec centerToScaleStart = scaleData.startPos - scaleData.centerPos; + Vector2f centerToScaleStartInCamSpace = drawP.world.drawData.cam.c.normalized_dir_to_space(centerToScaleStart.normalized()); + Vector2f scaleCenterPointInCamSpace = drawP.world.drawData.cam.c.to_space(scaleData.centerPos); + scaleData.currentPos = drawP.world.drawData.cam.c.from_space(project_point_on_line(motion.pos, scaleCenterPointInCamSpace, (scaleCenterPointInCamSpace + centerToScaleStartInCamSpace).eval())); + + WorldVec centerToScaleCurrent = scaleData.currentPos - scaleData.centerPos; + + WorldScalar centerToScaleStartNorm = centerToScaleStart.norm(); + WorldScalar centerToScaleCurrentNorm = centerToScaleCurrent.norm(); + bool isAnyNumberZero = centerToScaleCurrentNorm == WorldScalar(0) || centerToScaleStartNorm == WorldScalar(0); + + if(!isAnyNumberZero) { + WorldMultiplier scaleAmount = WorldMultiplier(centerToScaleStartNorm) / WorldMultiplier(centerToScaleCurrentNorm); + selectionTransformCoords = CoordSpaceHelperTransform(scaleData.centerPos, scaleAmount); + } + break; + } + case TransformOperation::ROTATE_RELOCATE_CENTER: { + rotateData.centerPos = drawP.world.drawData.cam.c.from_space(motion.pos); + break; + } + case TransformOperation::ROTATE: { + Vector2f rotationPointDiff = drawP.world.main.input.mouse.pos - rotateData.centerHandlePoint; + rotateData.rotationAngle = std::atan2(rotationPointDiff.y(), rotationPointDiff.x()); + selectionTransformCoords = CoordSpaceHelperTransform(rotateData.centerPos, rotateData.rotationAngle); + break; + } + } + } } void DrawingProgramSelection::translate_key(unsigned keyPressed, bool pressed) { @@ -703,7 +720,7 @@ void DrawingProgramSelection::rebuild_cam_space() { selectionRectPoints[2] = selectionTransformCoords.from_space_world(initialSelectionAABB.max); selectionRectPoints[3] = selectionTransformCoords.from_space_world(initialSelectionAABB.top_right()); - scaleData.handlePoint = drawP.world.drawData.cam.c.to_space(initialSelectionAABB.max); + scaleData.handlePoint = drawP.world.drawData.cam.c.to_space(selectionRectPoints[2]); rotateData.centerHandlePoint = drawP.world.drawData.cam.c.to_space(rotateData.centerPos); rotateData.handlePoint = get_rotation_point_pos_from_angle(rotateData.rotationAngle); diff --git a/src/DrawingProgram/DrawingProgramSelection.hpp b/src/DrawingProgram/DrawingProgramSelection.hpp index 62f9b4f..019c4c8 100644 --- a/src/DrawingProgram/DrawingProgramSelection.hpp +++ b/src/DrawingProgram/DrawingProgramSelection.hpp @@ -2,6 +2,7 @@ #include "../CoordSpaceHelperTransform.hpp" #include "Layers/DrawingProgramLayerManager.hpp" #include "DrawingProgramCache.hpp" +#include "../InputManager.hpp" class DrawingProgram; @@ -28,7 +29,10 @@ class DrawingProgramSelection { void delete_all(); void selection_to_clipboard(); CanvasComponentContainer::ObjInfo* get_front_object_colliding_with_in_editing_layer(const SCollision::ColliderCollection& cC); - void register_callbacks(); + void input_key_callback_modify_selection(const InputManager::KeyCallbackArgs& key); + void input_key_callback_display_selection(const InputManager::KeyCallbackArgs& key); + void input_mouse_button_on_canvas_callback_modify_selection(const InputManager::MouseButtonCallbackArgs& button); + void input_mouse_motion_callback_modify_selection(const InputManager::MouseMotionCallbackArgs& motion); private: void translate_key(unsigned keyPressed, bool pressed); bool mouse_collided_with_selection_aabb(); diff --git a/src/DrawingProgram/Tools/DrawingProgramToolBase.cpp b/src/DrawingProgram/Tools/DrawingProgramToolBase.cpp index 88985ac..642efb0 100644 --- a/src/DrawingProgram/Tools/DrawingProgramToolBase.cpp +++ b/src/DrawingProgram/Tools/DrawingProgramToolBase.cpp @@ -54,3 +54,7 @@ std::unique_ptr DrawingProgramToolBase::allocate_tool_ty } return nullptr; } + +void DrawingProgramToolBase::input_key_callback(const InputManager::KeyCallbackArgs& key) {} +void DrawingProgramToolBase::input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button) {} +void DrawingProgramToolBase::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) {} diff --git a/src/DrawingProgram/Tools/DrawingProgramToolBase.hpp b/src/DrawingProgram/Tools/DrawingProgramToolBase.hpp index fbd573d..c7e18c6 100644 --- a/src/DrawingProgram/Tools/DrawingProgramToolBase.hpp +++ b/src/DrawingProgram/Tools/DrawingProgramToolBase.hpp @@ -2,6 +2,7 @@ #include #include "../../DrawData.hpp" #include "../../CanvasComponents/CanvasComponentContainer.hpp" +#include "../../InputManager.hpp" class DrawingProgram; @@ -35,6 +36,9 @@ class DrawingProgramToolBase { virtual void draw(SkCanvas* canvas, const DrawData& drawData) = 0; virtual void switch_tool(DrawingProgramToolType newTool) = 0; virtual bool prevent_undo_or_redo() = 0; + virtual void input_key_callback(const InputManager::KeyCallbackArgs& key); + virtual void input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button); + virtual void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion); virtual ~DrawingProgramToolBase(); static std::unique_ptr allocate_tool_type(DrawingProgram& drawP, DrawingProgramToolType t); protected: diff --git a/src/DrawingProgram/Tools/LassoSelectTool.cpp b/src/DrawingProgram/Tools/LassoSelectTool.cpp index 548da8c..6b0c6b1 100644 --- a/src/DrawingProgram/Tools/LassoSelectTool.cpp +++ b/src/DrawingProgram/Tools/LassoSelectTool.cpp @@ -50,6 +50,68 @@ bool LassoSelectTool::right_click_popup_gui(Vector2f popupPos) { return drawP.selection_action_menu(popupPos); } +void LassoSelectTool::input_key_callback(const InputManager::KeyCallbackArgs& key) { + drawP.selection.input_key_callback_display_selection(key); + drawP.selection.input_key_callback_modify_selection(key); +} + +void LassoSelectTool::input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button) { + drawP.selection.input_mouse_button_on_canvas_callback_modify_selection(button); + if(!controls.isSelecting && button.button == InputManager::MouseButtonCallbackArgs::Button::LEFT && button.down && !drawP.selection.is_being_transformed()) { + controls = LassoSelectControls(); + controls.coords = drawP.world.drawData.cam.c; + controls.lassoPoints.emplace_back(controls.coords.get_mouse_pos(drawP.world)); + controls.isSelecting = true; + } + else if(controls.isSelecting && button.button == InputManager::MouseButtonCallbackArgs::Button::LEFT && !button.down) { + if(controls.lassoPoints.size() > 3) { + SCollision::ColliderCollection cC; + + std::vector> polygon; + polygon.emplace_back(controls.lassoPoints); + auto& poly = polygon[0]; + for(auto& v : poly) + v = drawP.world.drawData.cam.c.to_space(controls.coords.from_space(v)); + + std::vector indices = mapbox::earcut(polygon); + + for(size_t i = 0; i < indices.size(); i += 3) { + cC.triangle.emplace_back( + poly[indices[i]], + poly[indices[i + 1]], + poly[indices[i + 2]] + ); + } + + cC.recalculate_bounds(); + + if(drawP.world.main.input.key(InputManager::KEY_GENERIC_LSHIFT).held) + drawP.selection.add_from_cam_coord_collider_to_selection(cC, drawP.controls.layerSelector, false); + else if(drawP.world.main.input.key(InputManager::KEY_GENERIC_LALT).held) + drawP.selection.remove_from_cam_coord_collider_to_selection(cC, drawP.controls.layerSelector, false); + else { + drawP.selection.deselect_all(); + drawP.selection.add_from_cam_coord_collider_to_selection(cC, drawP.controls.layerSelector, false); + } + controls.lassoPoints.clear(); + } + else if(!drawP.world.main.input.key(InputManager::KEY_GENERIC_LSHIFT).held && !drawP.world.main.input.key(InputManager::KEY_GENERIC_LALT).held) { + drawP.selection.deselect_all(); + } + controls.isSelecting = false; + } +} + +void LassoSelectTool::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) { + if(controls.isSelecting) { + Vector2f newLassoPoint = controls.coords.to_space(drawP.world.drawData.cam.c.from_space(motion.pos)); + float lassoPointDist = vec_distance(controls.lassoPoints.back(), newLassoPoint); + if(lassoPointDist > 4.0f) + controls.lassoPoints.emplace_back(newLassoPoint); + } + drawP.selection.input_mouse_motion_callback_modify_selection(motion); +} + void LassoSelectTool::erase_component(CanvasComponentContainer::ObjInfo* erasedComp) { } @@ -59,68 +121,14 @@ void LassoSelectTool::switch_tool(DrawingProgramToolType newTool) { } void LassoSelectTool::tool_update() { - switch(controls.selectionMode) { - case 0: { - if(drawP.controls.leftClick && !drawP.selection.is_being_transformed()) { - controls = LassoSelectControls(); - 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); - float lassoPointDist = vec_distance(controls.lassoPoints.back(), newLassoPoint); - if(lassoPointDist > 4.0f) - controls.lassoPoints.emplace_back(newLassoPoint); - - if(!drawP.controls.leftClickHeld) { - if(controls.lassoPoints.size() > 3) { - SCollision::ColliderCollection cC; - - std::vector> polygon; - polygon.emplace_back(controls.lassoPoints); - auto& poly = polygon[0]; - - std::vector indices = mapbox::earcut(polygon); - - for(size_t i = 0; i < indices.size(); i += 3) { - cC.triangle.emplace_back( - poly[indices[i]], - poly[indices[i + 1]], - poly[indices[i + 2]] - ); - } - - cC.recalculate_bounds(); - - if(drawP.world.main.input.key(InputManager::KEY_GENERIC_LSHIFT).held) - drawP.selection.add_from_cam_coord_collider_to_selection(cC, drawP.controls.layerSelector, false); - else if(drawP.world.main.input.key(InputManager::KEY_GENERIC_LALT).held) - drawP.selection.remove_from_cam_coord_collider_to_selection(cC, drawP.controls.layerSelector, false); - else { - drawP.selection.deselect_all(); - drawP.selection.add_from_cam_coord_collider_to_selection(cC, drawP.controls.layerSelector, false); - } - } - else if(!drawP.world.main.input.key(InputManager::KEY_GENERIC_LSHIFT).held && !drawP.world.main.input.key(InputManager::KEY_GENERIC_LALT).held) { - drawP.selection.deselect_all(); - } - controls.selectionMode = 0; - } - break; - } - } } bool LassoSelectTool::prevent_undo_or_redo() { - return drawP.selection.is_something_selected() || controls.selectionMode == 1; + return drawP.selection.is_something_selected() || controls.isSelecting; } void LassoSelectTool::draw(SkCanvas* canvas, const DrawData& drawData) { - if(controls.selectionMode == 1) { + if(controls.isSelecting) { canvas->save(); controls.coords.transform_sk_canvas(canvas, drawData); diff --git a/src/DrawingProgram/Tools/LassoSelectTool.hpp b/src/DrawingProgram/Tools/LassoSelectTool.hpp index a981514..18e7a55 100644 --- a/src/DrawingProgram/Tools/LassoSelectTool.hpp +++ b/src/DrawingProgram/Tools/LassoSelectTool.hpp @@ -18,13 +18,13 @@ class LassoSelectTool : 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_key_callback(const InputManager::KeyCallbackArgs& key) 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; private: struct LassoSelectControls { - int selectionMode = 0; - + bool isSelecting = false; CoordSpaceHelper coords; - std::vector lassoPoints; } controls; }; diff --git a/src/DrawingProgram/Tools/RectSelectTool.cpp b/src/DrawingProgram/Tools/RectSelectTool.cpp index 5697c29..593db3d 100644 --- a/src/DrawingProgram/Tools/RectSelectTool.cpp +++ b/src/DrawingProgram/Tools/RectSelectTool.cpp @@ -24,6 +24,50 @@ void RectSelectTool::gui_toolbox() { t.gui.pop_id(); } +void RectSelectTool::input_key_callback(const InputManager::KeyCallbackArgs& key) { + drawP.selection.input_key_callback_display_selection(key); + drawP.selection.input_key_callback_modify_selection(key); +} + +void RectSelectTool::input_mouse_button_on_canvas_callback(const InputManager::MouseButtonCallbackArgs& button) { + drawP.selection.input_mouse_button_on_canvas_callback_modify_selection(button); + if(!controls.isSelecting && button.button == InputManager::MouseButtonCallbackArgs::Button::LEFT && button.down && !drawP.selection.is_being_transformed()) { + controls = RectSelectControls(); + controls.coords = drawP.world.drawData.cam.c; + controls.selectStartAt = controls.selectEndAt = button.pos; + controls.isSelecting = true; + } + else if(controls.isSelecting && button.button == InputManager::MouseButtonCallbackArgs::Button::LEFT && !button.down) { + using namespace SCollision; + controls.selectEndAt = controls.coords.to_space(drawP.world.drawData.cam.c.from_space(button.pos)); + Vector2f newP1 = drawP.world.drawData.cam.c.to_space(controls.coords.from_space(cwise_vec_min(controls.selectStartAt, controls.selectEndAt))); + Vector2f newP2 = drawP.world.drawData.cam.c.to_space(controls.coords.from_space(cwise_vec_max(controls.selectStartAt, controls.selectEndAt))); + std::array newT = triangle_from_rect_points(newP1, newP2); + + ColliderCollection cC; + cC.triangle.emplace_back(newT[0], newT[1], newT[2]); + cC.triangle.emplace_back(newT[2], newT[3], newT[0]); + cC.recalculate_bounds(); + + if(drawP.world.main.input.key(InputManager::KEY_GENERIC_LSHIFT).held) + drawP.selection.add_from_cam_coord_collider_to_selection(cC, drawP.controls.layerSelector, false); + else if(drawP.world.main.input.key(InputManager::KEY_GENERIC_LALT).held) + drawP.selection.remove_from_cam_coord_collider_to_selection(cC, drawP.controls.layerSelector, false); + else { + drawP.selection.deselect_all(); + drawP.selection.add_from_cam_coord_collider_to_selection(cC, drawP.controls.layerSelector, false); + } + + controls.isSelecting = false; + } +} + +void RectSelectTool::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) { + if(controls.isSelecting) + controls.selectEndAt = controls.coords.to_space(drawP.world.drawData.cam.c.from_space(motion.pos)); + drawP.selection.input_mouse_motion_callback_modify_selection(motion); +} + void RectSelectTool::erase_component(CanvasComponentContainer::ObjInfo* erasedComp) { } @@ -37,56 +81,24 @@ void RectSelectTool::switch_tool(DrawingProgramToolType newTool) { } void RectSelectTool::tool_update() { - switch(controls.selectionMode) { - case 0: { - if(drawP.controls.leftClick && !drawP.selection.is_being_transformed()) { - controls = RectSelectControls(); - controls.coords = drawP.world.drawData.cam.c; - controls.selectStartAt = controls.coords.get_mouse_pos(drawP.world); - controls.selectionMode = 1; - } - break; - } - case 1: { - using namespace SCollision; - Vector2f mPos = controls.coords.get_mouse_pos(drawP.world); - Vector2f newP1 = cwise_vec_min(controls.selectStartAt, mPos); - Vector2f newP2 = cwise_vec_max(controls.selectStartAt, mPos); - controls.newT = triangle_from_rect_points(newP1, newP2); - if(!drawP.controls.leftClickHeld) { - ColliderCollection cC; - cC.triangle.emplace_back(controls.newT[0], controls.newT[1], controls.newT[2]); - cC.triangle.emplace_back(controls.newT[2], controls.newT[3], controls.newT[0]); - cC.recalculate_bounds(); - - if(drawP.world.main.input.key(InputManager::KEY_GENERIC_LSHIFT).held) - drawP.selection.add_from_cam_coord_collider_to_selection(cC, drawP.controls.layerSelector, false); - else if(drawP.world.main.input.key(InputManager::KEY_GENERIC_LALT).held) - drawP.selection.remove_from_cam_coord_collider_to_selection(cC, drawP.controls.layerSelector, false); - else { - drawP.selection.deselect_all(); - drawP.selection.add_from_cam_coord_collider_to_selection(cC, drawP.controls.layerSelector, false); - } - - controls.selectionMode = 0; - } - break; - } - } } bool RectSelectTool::prevent_undo_or_redo() { - return drawP.selection.is_something_selected() || controls.selectionMode == 1; + return drawP.selection.is_something_selected() || controls.isSelecting; } void RectSelectTool::draw(SkCanvas* canvas, const DrawData& drawData) { - if(controls.selectionMode == 1) { + if(controls.isSelecting) { + Vector2f mPos = controls.selectEndAt; + Vector2f newP1 = cwise_vec_min(controls.selectStartAt, mPos); + Vector2f newP2 = cwise_vec_max(controls.selectStartAt, mPos); + std::array newT = triangle_from_rect_points(newP1, newP2); + canvas->save(); controls.coords.transform_sk_canvas(canvas, drawData); - SkRect r = SkRect::MakeLTRB(controls.newT[0].x(), controls.newT[0].y(), controls.newT[2].x(), controls.newT[2].y()); + SkRect r = SkRect::MakeLTRB(newT[0].x(), newT[0].y(), newT[2].x(), newT[2].y()); canvas->drawRect(r, drawP.select_tool_line_paint()); - canvas->restore(); canvas->restore(); } diff --git a/src/DrawingProgram/Tools/RectSelectTool.hpp b/src/DrawingProgram/Tools/RectSelectTool.hpp index 09fa1ff..1130c2f 100644 --- a/src/DrawingProgram/Tools/RectSelectTool.hpp +++ b/src/DrawingProgram/Tools/RectSelectTool.hpp @@ -16,11 +16,14 @@ class RectSelectTool : 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_key_callback(const InputManager::KeyCallbackArgs& key) 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; private: struct RectSelectControls { - int selectionMode = 0; + bool isSelecting = false; CoordSpaceHelper coords; Vector2f selectStartAt; - std::array newT; + Vector2f selectEndAt; } controls; }; diff --git a/src/InputManager.cpp b/src/InputManager.cpp index 727ee4e..21a3150 100644 --- a/src/InputManager.cpp +++ b/src/InputManager.cpp @@ -384,7 +384,7 @@ void InputManager::backend_mouse_button_up_update(const SDL_MouseButtonEvent& e) mouse.middleDown = false; else if(e.button == 3) mouse.rightDown = false; - mouseButtonCallbacks.run_callbacks({ + main.input_mouse_button_callback(MouseButtonCallbackArgs{ .button = static_cast(e.button), .down = e.down, .clicks = e.clicks, @@ -406,7 +406,7 @@ void InputManager::backend_mouse_button_down_update(const SDL_MouseButtonEvent& mouse.rightDown = true; mouse.rightClicks = e.clicks; } - mouseButtonCallbacks.run_callbacks({ + main.input_mouse_button_callback(MouseButtonCallbackArgs{ .button = static_cast(e.button), .down = e.down, .clicks = e.clicks, @@ -418,7 +418,7 @@ void InputManager::backend_mouse_motion_update(const SDL_MouseMotionEvent& e) { Vector2f mouseNewPos = {e.x * main.window.density, e.y * main.window.density}; Vector2f mouseRel = {e.xrel * main.window.density, e.yrel * main.window.density}; mouse.set_pos(mouseNewPos); - mouseMotionCallbacks.run_callbacks({ + main.input_mouse_motion_callback({ .pos = mouseNewPos, .move = mouseRel }); @@ -427,9 +427,6 @@ void InputManager::backend_mouse_motion_update(const SDL_MouseMotionEvent& e) { void InputManager::backend_mouse_wheel_update(const SDL_MouseWheelEvent& e) { mouse.scrollAmount.x() += e.x; mouse.scrollAmount.y() += e.y; - mouseWheelCallbacks.run_callbacks({ - .amount = {e.x, e.y}, - }); } void InputManager::backend_key_down_update(const SDL_KeyboardEvent& e) { @@ -447,8 +444,6 @@ void InputManager::backend_key_down_update(const SDL_KeyboardEvent& e) { if(stopKeyInput) return; - sdlKeyCallbacks.run_callbacks(e); - std::shared_ptr textBox = text.textBoxes.empty() ? nullptr : text.textBoxes.front().textBox; std::shared_ptr cursor = text.textBoxes.empty() ? nullptr : text.textBoxes.front().cursor; std::optional modMap = text.textBoxes.empty() ? std::nullopt : text.textBoxes.front().modMap; @@ -581,23 +576,22 @@ void InputManager::backend_key_down_update(const SDL_KeyboardEvent& e) { return; auto f = keyAssignments.find({make_generic_key_mod(kMod), kPress}); - KeyCallbackArgs keyArgs{.down = e.down, .repeat = e.repeat}; if(f != keyAssignments.end()) { set_key_down(e, f->second); - keyCallbacks[f->second].run_callbacks(keyArgs); + main.input_key_callback(KeyCallbackArgs{.key = f->second, .down = e.down, .repeat = e.repeat}); } switch(kPress) { case SDLK_UP: - keyCallbacks[KEY_TEXT_UP].run_callbacks(keyArgs); + main.input_key_callback(KeyCallbackArgs{.key = KEY_TEXT_UP, .down = e.down, .repeat = e.repeat}); break; case SDLK_DOWN: - keyCallbacks[KEY_TEXT_DOWN].run_callbacks(keyArgs); + main.input_key_callback(KeyCallbackArgs{.key = KEY_TEXT_DOWN, .down = e.down, .repeat = e.repeat}); break; case SDLK_LEFT: - keyCallbacks[KEY_TEXT_LEFT].run_callbacks(keyArgs); + main.input_key_callback(KeyCallbackArgs{.key = KEY_TEXT_LEFT, .down = e.down, .repeat = e.repeat}); break; case SDLK_RIGHT: - keyCallbacks[KEY_TEXT_RIGHT].run_callbacks(keyArgs); + main.input_key_callback(KeyCallbackArgs{.key = KEY_TEXT_RIGHT, .down = e.down, .repeat = e.repeat}); break; } } @@ -704,26 +698,25 @@ void InputManager::backend_key_up_update(const SDL_KeyboardEvent& e) { break; } - KeyCallbackArgs keyArgs{.down = e.down, .repeat = e.repeat}; for(auto& p : keyAssignments) { if(p.first.y() == kPress) { // Dont try matching modifiers when setting key to go up set_key_up(e, p.second); - keyCallbacks[p.second].run_callbacks(keyArgs); + main.input_key_callback(KeyCallbackArgs{.key = p.second, .down = e.down, .repeat = e.repeat}); } } switch(kPress) { case SDLK_UP: - keyCallbacks[KEY_TEXT_UP].run_callbacks(keyArgs); + main.input_key_callback(KeyCallbackArgs{.key = KEY_TEXT_UP, .down = e.down, .repeat = e.repeat}); break; case SDLK_DOWN: - keyCallbacks[KEY_TEXT_DOWN].run_callbacks(keyArgs); + main.input_key_callback(KeyCallbackArgs{.key = KEY_TEXT_DOWN, .down = e.down, .repeat = e.repeat}); break; case SDLK_LEFT: - keyCallbacks[KEY_TEXT_LEFT].run_callbacks(keyArgs); + main.input_key_callback(KeyCallbackArgs{.key = KEY_TEXT_LEFT, .down = e.down, .repeat = e.repeat}); break; case SDLK_RIGHT: - keyCallbacks[KEY_TEXT_RIGHT].run_callbacks(keyArgs); + main.input_key_callback(KeyCallbackArgs{.key = KEY_TEXT_RIGHT, .down = e.down, .repeat = e.repeat}); break; } } diff --git a/src/InputManager.hpp b/src/InputManager.hpp index 2491c09..ed7dc2e 100644 --- a/src/InputManager.hpp +++ b/src/InputManager.hpp @@ -235,14 +235,11 @@ struct InputManager { const KeyData& key(KeyCode kCode); - CallbackManager sdlKeyCallbacks; - struct KeyCallbackArgs { + KeyCode key; bool down; bool repeat; }; - typedef CallbackManager KeyCallbackManager; - std::array keyCallbacks; std::unordered_map keyAssignments; std::unordered_map defaultKeyAssignments; @@ -258,21 +255,15 @@ struct InputManager { uint8_t clicks; Vector2f pos; }; - typedef CallbackManager MouseButtonCallbackManager; - MouseButtonCallbackManager mouseButtonCallbacks; struct MouseMotionCallbackArgs { Vector2f pos; Vector2f move; }; - typedef CallbackManager MouseMotionCallbackManager; - MouseMotionCallbackManager mouseMotionCallbacks; struct MouseWheelCallbackArgs { Vector2f amount; }; - typedef CallbackManager MouseWheelCallbackManager; - MouseWheelCallbackManager mouseWheelCallbacks; MainProgram& main; }; diff --git a/src/MainProgram.cpp b/src/MainProgram.cpp index d58d630..b4ac7c4 100755 --- a/src/MainProgram.cpp +++ b/src/MainProgram.cpp @@ -62,19 +62,6 @@ MainProgram::MainProgram(): *logFile << "[CHAT] " << text << std::endl; std::cout << "[CHAT] " << text << std::endl; }); - - register_callbacks(); -} - -void MainProgram::register_callbacks() { - input.keyCallbacks[InputManager::KEY_NOGUI].register_callback([&](auto& keyData) { - if(keyData.down && !keyData.repeat) - drawGui = !drawGui; - }); - input.keyCallbacks[InputManager::KEY_FULLSCREEN].register_callback([&](auto& keyData) { - if(keyData.down && !keyData.repeat) - drawGui = !drawGui; - }); } void MainProgram::update() { @@ -114,8 +101,6 @@ void MainProgram::update() { if(oldWorld != world) { if(oldWorld) oldWorld->on_tab_out(); - if(world) - world->on_tab_in(); } deltaTime.update_time_since(); @@ -325,6 +310,32 @@ sk_sp MainProgram::create_native_surface(Vector2i resolution, bool is return surfaceToRet; } +void MainProgram::input_key_callback(const InputManager::KeyCallbackArgs& key) { + switch(key.key) { + case InputManager::KEY_NOGUI: { + if(key.down && !key.repeat) + drawGui = !drawGui; + break; + } + case InputManager::KEY_FULLSCREEN: { + if(key.down && !key.repeat) + drawGui = !drawGui; + } + } + if(world) + world->input_key_callback(key); +} + +void MainProgram::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) { + if(world) + world->input_mouse_button_callback(button); +} + +void MainProgram::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) { + if(world) + world->input_mouse_motion_callback(motion); +} + bool MainProgram::network_being_used() { for(auto& w : worlds) { if(w->netObjMan.is_connected()) diff --git a/src/MainProgram.hpp b/src/MainProgram.hpp index 2bf0ecb..52ee614 100644 --- a/src/MainProgram.hpp +++ b/src/MainProgram.hpp @@ -120,9 +120,12 @@ class MainProgram { std::string displayName; + void input_key_callback(const InputManager::KeyCallbackArgs& key); + void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button); + void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion); + ~MainProgram(); private: - void register_callbacks(); void new_tab_open(); std::atomic tabSetToOpen = false; World::OpenWorldInfo newTabToOpenInfo; diff --git a/src/World.cpp b/src/World.cpp index d2c6532..49fe2f5 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -151,9 +151,6 @@ void World::init_client(const std::string& serverFullID) { #endif clientStillConnecting = false; - - if(is_focus()) - register_callbacks(); }); netClient->add_recv_callback(CLIENT_UPDATE_NETWORK_OBJECT, [&](cereal::PortableBinaryInputArchive& message) { netObjMan.read_update_message(message, nullptr); @@ -248,32 +245,34 @@ void World::unfocus_update() { void World::on_tab_out() { rMan.clear_display_cache(); +} + +void World::input_key_callback(const InputManager::KeyCallbackArgs& key) { + if(!clientStillConnecting) { + switch(key.key) { + case InputManager::KEY_REDO: { + if(key.down) + redo_with_checks(); + break; + } + case InputManager::KEY_UNDO: { + if(key.down) + undo_with_checks(); + break; + } + } + drawProg.input_key_callback(key); + } +} + +void World::input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button) { if(!clientStillConnecting) - deregister_callbacks(); + drawProg.input_mouse_button_callback(button); } -void World::on_tab_in() { +void World::input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion) { if(!clientStillConnecting) - register_callbacks(); -} - -void World::register_callbacks() { - drawProg.register_callbacks(); - keyCallbacks[InputManager::KEY_REDO] = main.input.keyCallbacks[InputManager::KEY_REDO].register_callback([&](auto& key) { - if(key.down) - redo_with_checks(); - }); - keyCallbacks[InputManager::KEY_UNDO] = main.input.keyCallbacks[InputManager::KEY_UNDO].register_callback([&](auto& key) { - if(key.down) - undo_with_checks(); - }); -} - -void World::deregister_callbacks() { - drawProg.deregister_callbacks(); - for(auto& [key, callback] : keyCallbacks) - main.input.keyCallbacks[key].deregister_callback(callback); - keyCallbacks.clear(); + drawProg.input_mouse_motion_callback(motion); } void World::send_chat_message(const std::string& message) { diff --git a/src/World.hpp b/src/World.hpp index 60eae74..bc09024 100644 --- a/src/World.hpp +++ b/src/World.hpp @@ -67,7 +67,6 @@ class World { void focus_update(); void unfocus_update(); void on_tab_out(); - void on_tab_in(); void draw(SkCanvas* canvas, const DrawData& calledDrawData); void early_destroy(); @@ -102,11 +101,10 @@ class World { std::shared_ptr netServer; std::shared_ptr netClient; - std::unordered_map keyCallbacks; + void input_key_callback(const InputManager::KeyCallbackArgs& key); + void input_mouse_button_callback(const InputManager::MouseButtonCallbackArgs& button); + void input_mouse_motion_callback(const InputManager::MouseMotionCallbackArgs& motion); private: - void register_callbacks(); - void deregister_callbacks(); - void load_empty_canvas(); Vector3f get_random_cursor_color();