sifflet-0.1.5: Workspace/Functoid.hs
module Workspace.Functoid
(Functoid(..)
, functoidName, functoidArgNames, functoidHeader
, FunctoidLayout(..), flayout
, flayoutBBox, flayoutSize, flayoutWidth, flayoutBottom
, flayoutWiden)
where
import Data.Graph.Inductive as G
import Geometry
import Expr
import TreeLayout
-- | A Functoid is either a FunctoidParts, representing a partially
-- defined function, or a (completely defined) Function.
-- A FunctoidParts represents an incompletely defined function,
-- which has a function name, argument names, and a list of graph nodes
-- representing the function body which might not yet form
-- a complete expression tree, e.g., nodes might
-- be unconnected.
data Functoid = FunctoidParts {fpName :: String,
fpArgs :: [String],
fpNodes :: [G.Node]}
| FunctoidFunc {fpFunc :: Function}
deriving (Show)
functoidName :: Functoid -> String
functoidName (FunctoidParts {fpName = name}) = name
functoidName (FunctoidFunc function) = functionName function
functoidArgNames :: Functoid -> [String]
functoidArgNames (FunctoidParts {fpArgs = args}) = args
functoidArgNames (FunctoidFunc function) = functionArgNames function
functoidHeader :: Functoid -> String
functoidHeader f = unwords (functoidName f : functoidArgNames f)
-- | What is a FunctoidLayout? You can think of it as a
-- tree layout for a Frame,
-- or for a Functoid, or as a Forest of Tree Layouts!
-- For an Edit frame, it must be a forest, since the nodes are not
-- yet necessarily connected into a tree.
-- For a call frame, it will be a single TreeLayout (singleton list).
data FunctoidLayout = FLayoutTree (TreeLayout ExprNode)
| FLayoutForest [TreeLayout ExprNode] BBox
flayout :: Style -> Functoid -> Env -> [Value] -> FunctoidLayout
flayout style functoid env values =
case functoid of
FunctoidParts {} ->
-- *** STUB: [] and bbox
-- WELL: is this supposed to CREATE the tlo or RETRIEVE the tlo?
-- Either way, it won't work without access to the WGraph!
FLayoutForest [] (BBox (hpad style) (vpad style) 300 300)
FunctoidFunc function ->
let expr = functionBody function
exprTree = if null values
then exprToTree expr
else evalTree (exprToTree expr) env
tlo = treeLayout style (exprNodeIoletCounter env) exprTree
in FLayoutTree tlo
flayoutBBox :: FunctoidLayout -> BBox
flayoutBBox aflayout =
case aflayout of
FLayoutTree t -> layoutTreeBB t
FLayoutForest _ bbox -> bbox
flayoutSize :: FunctoidLayout -> Size
flayoutSize = bbSize . flayoutBBox
flayoutWidth :: FunctoidLayout -> Double
flayoutWidth = bbWidth . flayoutBBox
flayoutBottom :: FunctoidLayout -> Double
flayoutBottom = bbBottom . flayoutBBox
flayoutWiden :: FunctoidLayout -> Double -> FunctoidLayout
flayoutWiden aflayout minWidth =
case aflayout of
FLayoutTree t -> FLayoutTree (treeLayoutWiden t minWidth)
FLayoutForest f bbox -> FLayoutForest f bbox -- *** STUB ***
instance Draw FunctoidLayout where
draw style mode (FLayoutTree t) = draw style mode t
draw style mode (FLayoutForest f _) = draw style mode f
translate dx dy (FLayoutTree t) = FLayoutTree (translate dx dy t)
translate dx dy (FLayoutForest f b) =
FLayoutForest (translate dx dy f) (translate dx dy b)