factor/library/ui/shapes.factor

155 lines
4.1 KiB
Factor
Raw Normal View History

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
GENERIC: move-shape ( x y shape -- )
GENERIC: resize-shape ( w h 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
: max-width ( list -- n )
#! The width of the widest shape.
[ [ shape-w ] map [ > ] top ] [ 0 ] ifte* ;
2005-02-02 19:50:13 -05:00
: max-height ( list -- n )
#! The height of the tallest shape.
[ [ shape-h ] map [ > ] top ] [ 0 ] ifte* ;
: run-widths ( list -- w list )
#! Compute a list of running sums of widths of shapes.
[ 0 swap [ over , shape-w + ] each ] make-list ;
2005-02-02 19:50:13 -05:00
: run-heights ( list -- h list )
#! Compute a list of running sums of heights of shapes.
2005-02-02 19:50:13 -05:00
[ 0 swap [ over , shape-h + ] each ] make-list ;
2005-02-05 11:52:24 -05:00
! A point, represented as a complex number, is the simplest
! shape. It is not mutable and cannot be used as the delegate of
! a gadget.
: shape-pos ( shape -- pos )
dup shape-x swap shape-y rect> ;
2005-02-05 11:52:24 -05:00
M: number inside? ( point point -- )
>r shape-pos r> = ;
2005-02-05 11:52:24 -05:00
M: number shape-x real ;
M: number shape-y imaginary ;
M: number shape-w drop 0 ;
M: number shape-h drop 0 ;
: translate ( point shape -- point )
#! Translate a point relative to the shape.
2005-02-05 11:52:24 -05:00
swap shape-pos swap shape-pos - ;
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
M: rectangle move-shape ( x y rect -- )
tuck set-rectangle-y set-rectangle-x ;
2005-02-01 19:00:16 -05:00
M: rectangle resize-shape ( w h rect -- )
tuck set-rectangle-h set-rectangle-w ;
2005-02-01 19:00:16 -05:00
2005-02-01 20:14:03 -05:00
: rectangle-x-extents ( rect -- x1 x2 )
2005-02-05 11:52:24 -05:00
dup rectangle-x x get + swap rectangle-w 1 - dupd + ;
2005-01-31 14:02:09 -05:00
2005-02-01 20:14:03 -05:00
: rectangle-y-extents ( rect -- x1 x2 )
2005-02-05 11:52:24 -05:00
dup rectangle-y y get + swap rectangle-h 1 - 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 ;
! A line.
TUPLE: line x y w h ;
M: line shape-x line-x ;
M: line shape-y line-y ;
M: line shape-w line-w ;
M: line shape-h line-h ;
C: line ( x y w h -- line )
#! We handle negative w/h for convinience.
>r fix-neg >r fix-neg r> r>
[ set-line-h ] keep
[ set-line-w ] keep
[ set-line-y ] keep
[ set-line-x ] keep ;
M: line move-shape ( x y line -- )
tuck set-line-y set-line-x ;
M: line resize-shape ( w h line -- )
tuck set-line-h set-line-w ;
M: line inside? ( point line -- ? )
2005-02-06 00:21:26 -05:00
2drop t ;
! An ellipse.
TUPLE: ellipse x y w h ;
M: ellipse shape-x ellipse-x ;
M: ellipse shape-y ellipse-y ;
M: ellipse shape-w ellipse-w ;
M: ellipse shape-h ellipse-h ;
C: ellipse ( x y w h -- line )
2005-02-06 00:21:26 -05:00
#! We handle negative w/h for convenience.
>r fix-neg >r fix-neg r> r>
[ set-ellipse-h ] keep
[ set-ellipse-w ] keep
[ set-ellipse-y ] keep
[ set-ellipse-x ] keep ;
M: ellipse move-shape ( x y line -- )
tuck set-ellipse-y set-ellipse-x ;
M: ellipse resize-shape ( w h line -- )
tuck set-ellipse-h set-ellipse-w ;
2005-02-06 00:21:26 -05:00
M: ellipse inside? ( point ellipse -- ? )
ellipse>screen swap sq swap sq
2dup * >r >r >r
pick shape-y - sq
>r swap shape-x - sq r>
r> * r> rot * + r> <= ;