2005-01-31 14:02:09 -05:00
|
|
|
! Copyright (C) 2005 Slava Pestov.
|
|
|
|
! See http://factor.sf.net/license.txt for BSD license.
|
|
|
|
IN: gadgets
|
2005-02-02 19:50:13 -05:00
|
|
|
USING: generic kernel lists math namespaces ;
|
2005-01-31 14:02:09 -05:00
|
|
|
|
2005-02-01 19:00:16 -05:00
|
|
|
! Shape protocol. Shapes are immutable; moving or resizing a
|
|
|
|
! shape makes a new shape.
|
2005-01-31 14:02:09 -05:00
|
|
|
|
|
|
|
! These dynamically-bound variables affect the generic word
|
|
|
|
! inside?.
|
2005-02-01 19:00:16 -05:00
|
|
|
SYMBOL: x
|
|
|
|
SYMBOL: y
|
|
|
|
|
|
|
|
GENERIC: inside? ( point shape -- ? )
|
2005-01-31 14:02:09 -05:00
|
|
|
|
|
|
|
! A shape is an object with a defined bounding
|
|
|
|
! box, and a notion of interior.
|
|
|
|
GENERIC: shape-x
|
|
|
|
GENERIC: shape-y
|
|
|
|
GENERIC: shape-w
|
|
|
|
GENERIC: shape-h
|
|
|
|
|
2005-02-01 19:00:16 -05:00
|
|
|
GENERIC: move-shape ( x y shape -- shape )
|
|
|
|
GENERIC: resize-shape ( w h shape -- shape )
|
2005-01-31 14:02:09 -05:00
|
|
|
|
|
|
|
: with-translation ( shape quot -- )
|
|
|
|
#! All drawing done inside the quotation is translated
|
|
|
|
#! relative to the shape's origin.
|
|
|
|
[
|
|
|
|
>r dup
|
|
|
|
shape-x x [ + ] change
|
|
|
|
shape-y y [ + ] change
|
|
|
|
r> call
|
|
|
|
] with-scope ; inline
|
|
|
|
|
2005-02-02 19:50:13 -05:00
|
|
|
: translate ( point shape -- point )
|
|
|
|
#! Translate a point relative to the shape.
|
|
|
|
#! The rect>'ing of the given point won't be necessary as
|
|
|
|
#! soon as all generics delegate.
|
|
|
|
>r dup shape-x swap shape-y rect> r>
|
|
|
|
dup shape-x swap shape-y rect> - ;
|
|
|
|
|
|
|
|
: max-width ( list -- n )
|
|
|
|
#! The width of the widest shape.
|
|
|
|
[ shape-w ] map [ > ] top ;
|
|
|
|
|
|
|
|
: run-heights ( list -- h list )
|
|
|
|
#! Compute a list of accumilative sums of heights of shapes.
|
|
|
|
[ 0 swap [ over , shape-h + ] each ] make-list ;
|
|
|
|
|
2005-01-31 14:02:09 -05:00
|
|
|
! A point, represented as a complex number, is the simplest type
|
|
|
|
! of shape.
|
2005-02-01 19:00:16 -05:00
|
|
|
M: number inside? = ;
|
|
|
|
|
2005-01-31 14:02:09 -05:00
|
|
|
M: number shape-x real ;
|
|
|
|
M: number shape-y imaginary ;
|
|
|
|
M: number shape-w drop 0 ;
|
|
|
|
M: number shape-h drop 0 ;
|
2005-02-01 19:00:16 -05:00
|
|
|
|
|
|
|
M: number move-shape ( x y point -- point ) drop rect> ;
|
2005-01-31 14:02:09 -05:00
|
|
|
|
|
|
|
! A rectangle maps trivially to the shape protocol.
|
2005-02-01 20:14:03 -05:00
|
|
|
TUPLE: rectangle x y w h ;
|
|
|
|
M: rectangle shape-x rectangle-x ;
|
|
|
|
M: rectangle shape-y rectangle-y ;
|
|
|
|
M: rectangle shape-w rectangle-w ;
|
|
|
|
M: rectangle shape-h rectangle-h ;
|
2005-01-31 14:02:09 -05:00
|
|
|
|
|
|
|
: fix-neg ( a b c -- a+c b -c )
|
|
|
|
dup 0 < [ neg tuck >r >r + r> r> ] when ;
|
|
|
|
|
2005-02-01 20:14:03 -05:00
|
|
|
C: rectangle ( x y w h -- rect )
|
2005-01-31 14:02:09 -05:00
|
|
|
#! We handle negative w/h for convinience.
|
|
|
|
>r fix-neg >r fix-neg r> r>
|
2005-02-01 20:14:03 -05:00
|
|
|
[ set-rectangle-h ] keep
|
|
|
|
[ set-rectangle-w ] keep
|
|
|
|
[ set-rectangle-y ] keep
|
|
|
|
[ set-rectangle-x ] keep ;
|
2005-01-31 14:02:09 -05:00
|
|
|
|
2005-02-01 19:00:16 -05:00
|
|
|
M: number resize-shape ( w h point -- rect )
|
2005-02-01 20:14:03 -05:00
|
|
|
>rect 2swap <rectangle> ;
|
2005-02-01 19:00:16 -05:00
|
|
|
|
2005-02-01 20:14:03 -05:00
|
|
|
M: rectangle move-shape ( x y rect -- rect )
|
|
|
|
[ rectangle-w ] keep rectangle-h <rectangle> ;
|
2005-02-01 19:00:16 -05:00
|
|
|
|
2005-02-01 20:14:03 -05:00
|
|
|
M: rectangle resize-shape ( w h rect -- rect )
|
|
|
|
[ rectangle-x ] keep rectangle-y 2swap <rectangle> ;
|
2005-02-01 19:00:16 -05:00
|
|
|
|
2005-02-01 20:14:03 -05:00
|
|
|
: rectangle-x-extents ( rect -- x1 x2 )
|
|
|
|
dup rectangle-x x get + swap rectangle-w dupd + ;
|
2005-01-31 14:02:09 -05:00
|
|
|
|
2005-02-01 20:14:03 -05:00
|
|
|
: rectangle-y-extents ( rect -- x1 x2 )
|
|
|
|
dup rectangle-y y get + swap rectangle-h dupd + ;
|
2005-01-31 14:02:09 -05:00
|
|
|
|
2005-02-01 20:14:03 -05:00
|
|
|
M: rectangle inside? ( point rect -- ? )
|
|
|
|
over shape-x over rectangle-x-extents between? >r
|
|
|
|
swap shape-y swap rectangle-y-extents between? r> and ;
|
|
|
|
|
|
|
|
! Delegates to a bounded shape, but absorbs all points.
|
|
|
|
WRAPPER: everywhere
|
|
|
|
M: everywhere inside? ( point world -- ? ) 2drop t ;
|
|
|
|
|
|
|
|
M: everywhere move-shape ( x y everywhere -- )
|
|
|
|
everywhere-delegate move-shape <everywhere> ;
|
|
|
|
|
|
|
|
M: everywhere resize-shape ( w h everywhere -- )
|
|
|
|
everywhere-delegate resize-shape <everywhere> ;
|