mbrlabs / Lorien

Infinite canvas drawing/whiteboarding app for Windows, Linux and macOS. Made with Godot.
MIT License
5.54k stars 240 forks source link

Tool may be used outside canvas when selecting tool from off canvas #157

Closed hansemro closed 2 years ago

hansemro commented 2 years ago

Lorien version: bc83fbe6691c0879335d0f2577443bad076f47f3 80fdf7c14a6a5044581cac3ddf6badfefa38d6a5 v0.5.0 (release)

OS/device including version: Arch Linux w/ KDE

Issue description: After selecting any tool from off canvas (on menubar/toolbar/statusbar), you can use the selected tool from menubar/toolbar/statusbar as long as cursor does not enter canvas region while not in use. When cursor is not drawing/erasing/used and enters canvas region, user can no longer use the tool outside canvas region (expected behavior).

As later discovered, tool gets enabled on tool selection regardless of whether the cursor is on or off canvas.

Another unexpected behavior comes from selecting a tool from the toolbar. Because the tool gets enabled on selection and because the mouse button is pressed, the tool gets used when it shouldn't. Repeatedly pressing on drawing tools on the toolbar will add strokes to the canvas.

Steps to reproduce: 1) Select a tool from a toolbar or by keyboard shortcut off canvas 2) While keeping cursor off canvas, begin stroke from menubar, toolbar, or statusbar. You can continue to use the tool outside canvas as long as you start and end outside canvas region (and on window).

hansemro commented 2 years ago

Issue has to do with InfiniteCanvas::_active_tool.enabled being set true by the act of selecting a tool (even when off canvas).

Solution proposal: Let _active_tool.enabled keep the same enable status of the previous tool. We can just let Main::func _on_InfiniteCanvas_mouse_entered and Main::func _on_InfiniteCanvas_mouse_exited enable/disable the tools.

InfiniteCanvas.gd::use_tool

func use_tool(tool_type: int) -> void:
    var prev_tool := _active_tool
    var prev_status := prev_tool.enabled

    match tool_type:
        Types.Tool.BRUSH:
            _active_tool = _brush_tool
            _use_optimizer = true
        Types.Tool.RECTANGLE:
            _active_tool = _rectangle_tool
            _use_optimizer = false
        Types.Tool.CIRCLE:
            _active_tool = _circle_tool
            _use_optimizer = false
        Types.Tool.LINE:
            _active_tool = _line_tool
            _use_optimizer = false
        Types.Tool.ERASER:
            _active_tool = _eraser_tool
            _use_optimizer = false
        Types.Tool.SELECT:
            _active_tool = _selection_tool
            _use_optimizer = false

    if prev_tool != _active_tool:
        prev_tool.enabled = false
        prev_tool.reset()
    _active_tool.enabled = prev_status
    _active_tool.get_cursor()._on_zoom_changed(_camera.zoom.x)