wumpus-drawing-0.1.0: src/Wumpus/Drawing/Arrows/Connectors.hs
{-# OPTIONS -Wall #-}
--------------------------------------------------------------------------------
-- |
-- Module : Wumpus.Drawing.Arrows.Connectors
-- Copyright : (c) Stephen Tetley 2010
-- License : BSD3
--
-- Maintainer : Stephen Tetley <stephen.tetley@gmail.com>
-- Stability : highly unstable
-- Portability : GHC
--
-- Draw arrows.
--
--------------------------------------------------------------------------------
module Wumpus.Drawing.Arrows.Connectors
(
ArrowConnector
, leftArrow
, rightArrow
, leftRightArrow
, uniformArrow
) where
import Wumpus.Basic.Kernel
import Wumpus.Drawing.Arrows.Tips
import Wumpus.Drawing.Paths
-- An arrowhead always know how to draw itself (filled triangle,
-- stroked barb, etc.)
--
-- A Path is currently always drawn with openStroke,
-- eventually there might be scope for drawing
-- e.g. parallel lines ====
--
-- | A connector with arrow tips. The connector is an /Image/,
-- drawing it returns the path - positions can be taken on the
-- path (e.g. @midpoint@) for further decoration.
--
type ArrowConnector u = ConnectorImage u (Path u)
-- | Connector with an arrow tip at the start point \/ left.
--
leftArrow :: (Real u, Floating u)
=> Arrowhead u -> ConnectorPath u -> ArrowConnector u
leftArrow arrh conn = promoteR2 $ \p0 p1 ->
connect conn p0 p1 >>= \cpath ->
arrowhead_retract_dist arrh >>= \dl ->
let path1 = shortenL dl cpath
ang = directionL path1
g1 = openStroke $ toPrimPath path1
g2 = atRot (arrowhead_draw arrh) p0 ang
in fmap (replaceL cpath) $ g1 `oplus` g2
-- Note - returns original path
-- | Connector with an arrow tip at the end point \/ right.
--
rightArrow :: (Real u, Floating u)
=> Arrowhead u -> ConnectorPath u -> ArrowConnector u
rightArrow arrh conn = promoteR2 $ \p0 p1 ->
connect conn p0 p1 >>= \cpath ->
arrowhead_retract_dist arrh >>= \dr ->
let path1 = shortenR dr cpath
ang = directionR path1
g1 = openStroke $ toPrimPath path1
g2 = atRot (arrowhead_draw arrh) p1 ang
in fmap (replaceL cpath) $ g1 `oplus` g2
-- | Connector with two arrow tips, possibly different.
--
leftRightArrow :: (Real u, Floating u)
=> Arrowhead u -> Arrowhead u -> ConnectorPath u
-> ArrowConnector u
leftRightArrow arrL arrR conn = promoteR2 $ \p0 p1 ->
connect conn p0 p1 >>= \cpath ->
arrowhead_retract_dist arrL >>= \dL ->
arrowhead_retract_dist arrR >>= \dR ->
let path1 = shortenPath dL dR cpath
angL = directionL path1
angR = directionR path1
g1 = openStroke $ toPrimPath path1
gL = atRot (arrowhead_draw arrL) p0 angL
gR = atRot (arrowhead_draw arrR) p1 angR
in fmap (replaceL cpath) $ g1 `oplus` gL `oplus` gR
-- | Connector with the same arrow tip at both ends.
--
uniformArrow :: (Real u, Floating u)
=> Arrowhead u -> ConnectorPath u -> ArrowConnector u
uniformArrow arrh cp = leftRightArrow arrh arrh cp