prefer point drag over curve drag

This commit is contained in:
sheaf 2024-10-25 13:44:01 +02:00
parent 7b1dcefd46
commit bb237d99c8

View file

@ -34,7 +34,7 @@ import Data.Kind
( Type ) ( Type )
import qualified Data.List.NonEmpty as NE import qualified Data.List.NonEmpty as NE
import Data.Maybe import Data.Maybe
( fromMaybe, isNothing, listToMaybe ) ( fromMaybe, isJust, isNothing, listToMaybe )
import Data.Ratio import Data.Ratio
import Data.Semigroup import Data.Semigroup
( Arg(..), Min(..) ) ( Arg(..), Min(..) )
@ -319,8 +319,7 @@ selectAt selMode c doc@( Document { documentContent, documentMetadata } ) =
-- | Checks whether a mouse click can initiate a drag move event. -- | Checks whether a mouse click can initiate a drag move event.
dragMoveSelect :: 2 -> Document -> Maybe DragMoveSelect dragMoveSelect :: 2 -> Document -> Maybe DragMoveSelect
dragMoveSelect c ( Document { documentContent, documentMetadata } ) = dragMoveSelect c ( Document { documentContent, documentMetadata } ) =
( \case { Left drag -> Just drag; Right {} -> Nothing } ) $ ( `State.execState` Nothing ) $
Except.runExcept $
forStrokeHierarchy forStrokeHierarchy
( layerMetadata documentMetadata ) ( layerMetadata documentMetadata )
( strokeHierarchy documentContent ) ( strokeHierarchy documentContent )
@ -333,7 +332,7 @@ dragMoveSelect c ( Document { documentContent, documentMetadata } ) =
inSelectionRange p = inSelectionRange p =
squaredNorm ( c --> p :: T ( 2 ) ) * zoomFactor ^ ( 2 :: Int ) < 16 squaredNorm ( c --> p :: T ( 2 ) ) * zoomFactor ^ ( 2 :: Int ) < 16
dragSelect :: WithinParent Unique -> Stroke -> StrokeMetadata -> Except DragMoveSelect UpdateStroke dragSelect :: WithinParent Unique -> Stroke -> StrokeMetadata -> State ( Maybe DragMoveSelect ) UpdateStroke
dragSelect ( WithinParent _ strokeUnique ) ( Stroke { strokeSpline } ) ( StrokeMetadata { strokeVisible, strokeLocked } ) = do dragSelect ( WithinParent _ strokeUnique ) ( Stroke { strokeSpline } ) ( StrokeMetadata { strokeVisible, strokeLocked } ) = do
when ( strokeVisible && not strokeLocked ) $ when ( strokeVisible && not strokeLocked ) $
ibifoldSpline ibifoldSpline
@ -349,14 +348,25 @@ dragMoveSelect c ( Document { documentContent, documentMetadata } ) =
-> PointData brushParams -> PointData brushParams
-> Int -> Int
-> PointData brushParams -> Curve clo' ( CurveData RealWorld ) ( PointData brushParams ) -> PointData brushParams -> Curve clo' ( CurveData RealWorld ) ( PointData brushParams )
-> Except DragMoveSelect () -> State ( Maybe DragMoveSelect ) ()
dragSelectSplineCurve uniq start i sp0 = \case dragSelectSplineCurve uniq start i sp0 crv = do
mbPrevDrag <- State.get
case mbPrevDrag of
-- If we've clicked on a point, don't try anything further.
Just ( ClickedOnPoint {} ) -> return ()
_notPointDrag -> do
-- If we've already initiated a curve drag, don't try
-- another curve drag. However, we allow overridding a curve drag
-- by a point drag.
let clickedOnCurve = isJust mbPrevDrag
case crv of
LineTo sp1 ( CurveData { curveIndex } ) -> do LineTo sp1 ( CurveData { curveIndex } ) -> do
-- Check endpoints first. -- Check endpoints first.
traverse_ ( dragSelectSplinePoint uniq ( PointIndex curveIndex PathPoint ) ) sp1 traverse_ ( dragSelectSplinePoint uniq ( PointIndex curveIndex PathPoint ) ) sp1
let let
mbCurveDrag :: Maybe DragMoveSelect mbCurveDrag :: Maybe DragMoveSelect
mbCurveDrag = do mbCurveDrag = do
guard ( not clickedOnCurve )
let let
t :: Double t :: Double
p :: 2 p :: 2
@ -372,7 +382,7 @@ dragMoveSelect c ( Document { documentContent, documentMetadata } ) =
, dragCurveIndex = i , dragCurveIndex = i
, dragCurveParameter = t , dragCurveParameter = t
} }
for_ mbCurveDrag Except.throwE for_ mbCurveDrag $ State.put . Just
Bezier2To sp1 sp2 ( CurveData { curveIndex } ) -> do Bezier2To sp1 sp2 ( CurveData { curveIndex } ) -> do
-- Check endpoints first. -- Check endpoints first.
dragSelectSplinePoint uniq ( PointIndex curveIndex ( ControlPoint Bez2Cp ) ) sp1 dragSelectSplinePoint uniq ( PointIndex curveIndex ( ControlPoint Bez2Cp ) ) sp1
@ -380,6 +390,7 @@ dragMoveSelect c ( Document { documentContent, documentMetadata } ) =
let let
mbCurveDrag :: Maybe DragMoveSelect mbCurveDrag :: Maybe DragMoveSelect
mbCurveDrag = do mbCurveDrag = do
guard ( not clickedOnCurve )
let let
bez :: Quadratic.Bezier ( 2 ) bez :: Quadratic.Bezier ( 2 )
bez = Quadratic.Bezier ( coords sp0 ) ( coords sp1 ) ( coords $ fromNextPoint start sp2 ) bez = Quadratic.Bezier ( coords sp0 ) ( coords sp1 ) ( coords $ fromNextPoint start sp2 )
@ -395,7 +406,7 @@ dragMoveSelect c ( Document { documentContent, documentMetadata } ) =
, dragCurveIndex = i , dragCurveIndex = i
, dragCurveParameter = t , dragCurveParameter = t
} }
for_ mbCurveDrag Except.throwE for_ mbCurveDrag $ State.put . Just
Bezier3To sp1 sp2 sp3 ( CurveData { curveIndex } ) -> do Bezier3To sp1 sp2 sp3 ( CurveData { curveIndex } ) -> do
-- Check endpoints first. -- Check endpoints first.
dragSelectSplinePoint uniq ( PointIndex curveIndex ( ControlPoint Bez3Cp1 ) ) sp1 dragSelectSplinePoint uniq ( PointIndex curveIndex ( ControlPoint Bez3Cp1 ) ) sp1
@ -404,6 +415,7 @@ dragMoveSelect c ( Document { documentContent, documentMetadata } ) =
let let
mbCurveDrag :: Maybe DragMoveSelect mbCurveDrag :: Maybe DragMoveSelect
mbCurveDrag = do mbCurveDrag = do
guard ( not clickedOnCurve )
let let
bez :: Cubic.Bezier ( 2 ) bez :: Cubic.Bezier ( 2 )
bez = Cubic.Bezier ( coords sp0 ) ( coords sp1 ) ( coords sp2 ) ( coords $ fromNextPoint start sp3 ) bez = Cubic.Bezier ( coords sp0 ) ( coords sp1 ) ( coords sp2 ) ( coords $ fromNextPoint start sp3 )
@ -419,11 +431,15 @@ dragMoveSelect c ( Document { documentContent, documentMetadata } ) =
, dragCurveIndex = i , dragCurveIndex = i
, dragCurveParameter = t , dragCurveParameter = t
} }
for_ mbCurveDrag Except.throwE for_ mbCurveDrag $ State.put . Just
dragSelectSplinePoint :: Unique -> PointIndex -> PointData brushParams -> Except DragMoveSelect () dragSelectSplinePoint :: Unique -> PointIndex -> PointData brushParams -> State ( Maybe DragMoveSelect ) ()
dragSelectSplinePoint u ptIx pt = dragSelectSplinePoint u ptIx pt =
when ( inSelectionRange ( coords pt ) ) do when ( inSelectionRange ( coords pt ) ) do
mbPrevDrag <- State.get
case mbPrevDrag of
Just ( ClickedOnPoint {} ) -> return ()
_ -> do
let let
drag :: DragMoveSelect drag :: DragMoveSelect
drag = ClickedOnPoint drag = ClickedOnPoint
@ -431,7 +447,7 @@ dragMoveSelect c ( Document { documentContent, documentMetadata } ) =
, dragPointWasSelected = , dragPointWasSelected =
elemStrokePoint u ptIx ( selectedPoints documentMetadata ) elemStrokePoint u ptIx ( selectedPoints documentMetadata )
} }
Except.throwE drag State.put $ Just drag
addOrRemove :: SelectionMode addOrRemove :: SelectionMode