factor/library/ui/gadgets/scrolling.factor

102 lines
2.9 KiB
Factor
Raw Normal View History

2006-05-26 02:29:44 -04:00
! Copyright (C) 2005, 2006 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
IN: gadgets-scrolling
2006-06-12 03:21:08 -04:00
USING: arrays gadgets gadgets-frames gadgets-theme
gadgets-viewports generic kernel math namespaces sequences ;
! A scroller combines a viewport with two x and y sliders.
2006-07-19 19:30:02 -04:00
! The follows slot is a boolean, if true scroller will scroll
! down on the next relayout.
2005-10-10 21:12:53 -04:00
TUPLE: scroller viewport x y follows ;
2006-07-19 19:30:02 -04:00
: scroller-origin ( scroller -- { x y } )
2005-08-29 18:18:10 -04:00
dup scroller-x slider-value
swap scroller-y slider-value
2006-06-23 00:06:53 -04:00
2array ;
2005-08-29 18:18:10 -04:00
: find-scroller [ scroller? ] find-parent ;
2006-05-24 03:23:45 -04:00
: scroll-up-line scroller-y -1 swap slide-by-line ;
: scroll-down-line scroller-y 1 swap slide-by-line ;
scroller H{
{ T{ wheel-up } [ scroll-up-line ] }
{ T{ wheel-down } [ scroll-down-line ] }
{ T{ slider-changed } [ relayout-1 ] }
} set-gestures
2005-02-27 16:51:12 -05:00
2006-05-24 03:23:45 -04:00
C: scroller ( gadget -- scroller )
#! Wrap a scrolling pane around the gadget.
{
{ [ <viewport> ] set-scroller-viewport f @center }
{ [ <x-slider> ] set-scroller-x f @bottom }
{ [ <y-slider> ] set-scroller-y f @right }
2006-05-24 20:28:49 -04:00
} make-frame*
2006-06-12 03:21:08 -04:00
t over set-gadget-root?
dup faint-boundary ;
2005-03-07 23:15:00 -05:00
2006-05-24 03:23:45 -04:00
: set-slider ( value page max slider -- )
2005-08-27 01:41:42 -04:00
#! page/max/value are 3-vectors.
[ [ gadget-orientation v. ] keep set-slider-max ] keep
[ [ gadget-orientation v. ] keep set-slider-page ] keep
2006-05-24 03:23:45 -04:00
[ [ gadget-orientation v. ] keep set-slider-value* ] keep
slider-elevator relayout-1 ;
2005-08-27 01:41:42 -04:00
2005-08-29 18:18:10 -04:00
: update-slider ( scroller value slider -- )
2006-05-24 03:23:45 -04:00
>r swap scroller-viewport dup rect-dim swap viewport-dim
r> set-slider ;
2005-06-23 03:15:44 -04:00
: position-viewport ( scroller -- )
dup scroller-origin vneg
swap scroller-viewport gadget-child
set-rect-loc ;
2005-08-29 18:18:10 -04:00
: scroll ( scroller value -- )
2dup over scroller-x update-slider
dupd over scroller-y update-slider
position-viewport ;
2005-02-27 16:00:55 -05:00
2006-08-03 16:25:20 -04:00
: include-point ( point rect -- rect )
rect-extent >r over r> vmax >r vmin r> <extent-rect> ;
: scroll>point ( point scroller -- )
[
scroller-viewport [ include-point ] keep
[ rect-extent v+ ] 2apply v-
] keep dup scroller-origin rot v+ scroll ;
2006-08-03 17:17:22 -04:00
: (scroll>rect) ( rect scroller -- )
2006-08-03 16:25:20 -04:00
#! First ensure top left is visible, then bottom right.
2006-08-03 17:17:22 -04:00
>r rect-extent r> tuck
>r >r scroll>point r> r> scroll>point ;
: scroll>rect ( rect gadget -- )
find-scroller dup [ set-scroller-follows ] [ 2drop ] if ;
2006-08-03 16:25:20 -04:00
2006-07-19 20:23:08 -04:00
: scroll>bottom ( gadget -- )
2006-08-03 17:17:22 -04:00
t swap scroll>rect ;
: (scroll>bottom) ( scroller -- )
dup scroller-viewport viewport-dim { 0 1 } v* scroll ;
2005-10-23 16:18:07 -04:00
: update-scroller ( scroller -- )
2006-08-03 17:17:22 -04:00
dup scroller-follows dup [
f pick set-scroller-follows
dup t eq? [
drop (scroll>bottom)
] [
swap (scroll>rect)
] if
] [
2006-08-03 17:17:22 -04:00
drop dup scroller-origin scroll
] if ;
2006-05-24 03:23:45 -04:00
M: scroller layout* ( scroller -- )
dup delegate layout*
dup layout-children
update-scroller ;
2005-08-27 15:12:37 -04:00
M: scroller focusable-child* ( scroller -- viewport )
scroller-viewport ;