module TreeBrowser(Tree(..),treeBrowserF',treeDisplayF') where import AllFudgets hiding (Tree(..)) import qualified ReactiveF as R data Tree leaf node = Leaf leaf | Node node [Tree leaf node] deriving (Show) --treeBrowserF = treeBrowserF standard treeDisplayF' t = treeBrowserF'' drawStaticTree t treeBrowserF' t = treeBrowserF'' drawTree t --treeBrowserF' ::Tree n l -> F (Tree n l) ([n],Maybe l) treeBrowserF'' drawTree t = wCreateGCtx rootGCtx (gcFgA linecolor) $ \ lgc -> wCreateGCtx rootGCtx (gcFgA paperColor) $ \ bggc -> treeBrowserF''' drawTree (bggc,lgc) t treeBrowserF''' drawTree gcs@(bggc,lgc) t = loopThroughRightF (R.reactiveF ctrl d0) (graphicsDispF' pm) where pm1 :: Graphic a => Customiser (GraphicsF a) pm1 = setBgColor bgColor . setSizing Dynamic pm = pm1 . setInitDisp d0 d0 = drawTree gs t ctrl = either fromLoop fromOutside where fromOutside t = do let d = drawTree gs t R.set d R.put (toLoop $ replaceAllGfx d) fromLoop gfxevent = do (path,lbl) <- clickedpart gfxevent case lbl of Left vis -> toggle path (not vis) Right part -> R.put (toOutside part) toggle path vis = do (ppath,LabelD rt@(Right (Node n _)) (ComposedD _ (_:ds))) <- parentpathpart path let td' = LabelD rt (nodeD gs vis n ds) R.update $ \ d -> replacePart d ppath td' R.put (toLoop $ replaceGfx ppath td') toLoop = Left toOutside = Right --gd = softAttribD [GCLineStyle LineOnOffDash] . g --gd x = g x gl = hardAttribD lgc . g gbg = hardAttribD bggc . g gs = (gbg,gl) clickedpart gfxevent = case gfxevent of GfxButtonEvent{gfxType=Pressed, gfxPaths=(path,_):_} -> pathlbl path _ -> R.rfail pathlbl path = do (lpath,LabelD lbl _) <- pathpart path return (lpath,lbl) pathpart path = do drawing <- R.get let lpath = drawingAnnotPart drawing path part <- R.lift $ maybeDrawingPart drawing lpath return (lpath,part) parentpathpart = pathpart . up drawStaticTree gs t = placedD (verticalLeftP' 0) $ drawTree' gs Nothing t drawTree gs t = placedD (verticalLeftP' 0) $ drawTree' gs opendepthlimit t staticNodeD gs n ds = boxD (hboxD' 0 [sframeD 3 gs (g n)]:ds) nodeD gs@(gbg,gl) vis n ds = boxVisibleD vcnt (hboxD' 0 [sframeD 3 gs (g n),gl hLineFD,markD]:ds) where vcnt = 1+(if vis then length ds else 0) markD = labelD (Left vis) $ circleD (if vis then g "-" else g "+") circleD d = spacedD centerS $ stackD [gbg filledEllipse,gl ellipse,spacedD sqpadS d] where sqpadS = resizeS sq `compS` centerS sq (Point w h) = Point m m where m = max w h sframeD sep gs d = spacedD (vMarginS sep 0) $ frameD gs d frameD (gbg,gl) d = stackD [gbg $ filler False False 1,gl frame,padD 2 d] nodeD' gs Nothing = staticNodeD gs nodeD' gs (Just d) = nodeD gs (d>0) drawTree' gs@(_,gl) depth t = spacedD leftS $ labelD (Right t) $ case t of Leaf l -> --hboxD' 0 [gl hLineFD,frameD gs $ g l] sframeD 1 gs $ g l Node n ts -> nodeD' gs depth n [drawTrees gs (fmap (+(-1)) depth) ts] drawTrees gs@(_,gl) depth ts = vboxlD' 0 $ zipWith drawSubTree [n-1,n-2..0] ts where n = length ts drawSubTree i t = placedD (tableP' 2 Vertical 0) $ boxD [fork i,line i,drawTree' gs depth t] --drawSubTree i t = hboxD' 0 [fork i,drawTree' gs depth t] fork 0 = gl lowerRightFD fork _ = gl forkRightFD line 0 = blankD 0 line _ = gl vLineFD --- lowerRightFD = flex' (pP 14 10) f where f (Rect p s) = [DrawLines CoordModePrevious [p+pP mw 0,pP 0 mh,pP mw 0]] where Point mw mh = rectMiddle (Rect 0 s) forkRightFD = flex' (pP 14 10) f where f (Rect p s@(Point w h)) = [DrawLine (Line (p+pP mw 0) (p+pP mw h)), DrawLine (Line (p+m) (p+pP w mh))] where m@(Point mw mh) = rectMiddle (Rect 0 s) vLineFD = flex' (pP 10 1) f where f (Rect p s@(Point _ h)) = [DrawLine (Line (p+pP mw 0) (p+pP mw h))] where Point mw _ = rectMiddle (Rect 0 s) hLineFD = flex' 10 f where f (Rect p s@(Point w _)) = [DrawLine (Line (p+pP 0 mh) (p+pP w mh))] where Point _ mh = rectMiddle (Rect 0 s) linecolor = argKey "linecolor" "blue" opendepthlimit = argReadKey "opendepthlimit" (Just opendepth) -- not a good name opendepth = argReadKey "opendepth" 1::Int