factor/basis/ui/traverse/traverse.factor

87 lines
2.2 KiB
Factor

! Copyright (C) 2007 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
USING: namespaces sequences kernel math arrays io ui.gadgets
generic combinators ;
IN: ui.traverse
TUPLE: node value children ;
: traverse-step ( path gadget -- path' gadget' )
>r unclip r> gadget-children ?nth ;
: make-node ( quot -- ) { } make node boa , ; inline
: traverse-to-path ( topath gadget -- )
dup not [
2drop
] [
over empty? [
nip ,
] [
[
2dup gadget-children swap first head-slice %
tuck traverse-step traverse-to-path
] make-node
] if
] if ;
: traverse-from-path ( frompath gadget -- )
dup not [
2drop
] [
over empty? [
nip ,
] [
[
2dup traverse-step traverse-from-path
tuck gadget-children swap first 1+ tail-slice %
] make-node
] if
] if ;
: traverse-pre ( frompath gadget -- )
traverse-step traverse-from-path ;
: (traverse-middle) ( frompath topath gadget -- )
>r >r first 1+ r> first r> gadget-children <slice> % ;
: traverse-post ( topath gadget -- )
traverse-step traverse-to-path ;
: traverse-middle ( frompath topath gadget -- )
[
3dup nip traverse-pre
3dup (traverse-middle)
2dup traverse-post
2nip
] make-node ;
DEFER: (gadget-subtree)
: traverse-child ( frompath topath gadget -- )
dup -roll [
>r >r rest-slice r> r> traverse-step (gadget-subtree)
] make-node ;
: (gadget-subtree) ( frompath topath gadget -- )
{
{ [ dup not ] [ 3drop ] }
{ [ pick empty? pick empty? and ] [ 2nip , ] }
{ [ pick empty? ] [ rot drop traverse-to-path ] }
{ [ over empty? ] [ nip traverse-from-path ] }
{ [ pick first pick first = ] [ traverse-child ] }
[ traverse-middle ]
} cond ;
: gadget-subtree ( frompath topath gadget -- seq )
[ (gadget-subtree) ] { } make ;
M: node gadget-text*
dup node-children swap node-value gadget-seq-text ;
: gadget-text-range ( frompath topath gadget -- str )
gadget-subtree gadget-text ;
: gadget-at-path ( parent path -- gadget )
[ swap nth-gadget ] each ;