factor/basis/ui/gadgets/sliders/sliders.factor

246 lines
6.8 KiB
Factor
Raw Normal View History

! Copyright (C) 2005, 2010 Slava Pestov.
2007-09-20 18:09:08 -04:00
! See http://factorcode.org/license.txt for BSD license.
2015-01-29 14:41:18 -05:00
USING: accessors assocs combinators fry kernel math math.order
math.vectors models models.range ui.gadgets ui.gadgets.buttons
ui.gadgets.icons ui.gadgets.tracks ui.gestures ui.pens
ui.pens.image ui.pens.tile ui.theme.images ;
2007-09-20 18:09:08 -04:00
IN: ui.gadgets.sliders
2009-02-12 02:40:18 -05:00
TUPLE: slider < track elevator thumb saved line ;
: slider-value ( gadget -- n ) model>> range-value ;
2009-02-12 02:40:18 -05:00
: slider-page ( gadget -- n ) model>> range-page-value ;
: slider-min ( gadget -- n ) model>> range-min-value ;
2009-02-12 02:40:18 -05:00
: slider-max ( gadget -- n ) model>> range-max-value ;
: slider-max* ( gadget -- n ) model>> range-max-value* ;
: slider-length ( gadget -- n ) [ slider-max ] [ slider-min ] bi - ;
: slider-length* ( gadget -- n ) [ slider-max* ] [ slider-min ] bi - ;
2009-02-12 02:40:18 -05:00
: slide-by ( amount slider -- ) model>> move-by ;
: slide-by-page ( amount slider -- ) model>> move-by-page ;
: slide-by-line ( amount slider -- ) [ line>> * ] keep slide-by ;
<PRIVATE
TUPLE: elevator < gadget direction ;
2007-09-20 18:09:08 -04:00
2008-07-15 15:12:23 -04:00
: find-slider ( gadget -- slider/f ) [ slider? ] find-parent ;
2007-09-20 18:09:08 -04:00
2009-02-12 02:40:18 -05:00
CONSTANT: elevator-padding 4
2007-09-20 18:09:08 -04:00
: elevator-length ( slider -- n )
2009-02-12 02:40:18 -05:00
[ elevator>> dim>> ] [ orientation>> ] bi v.
elevator-padding 2 * - ;
2007-09-20 18:09:08 -04:00
2009-02-12 02:40:18 -05:00
CONSTANT: min-thumb-dim 30
2007-09-20 18:09:08 -04:00
2009-02-12 02:40:18 -05:00
: visible-portion ( slider -- n )
[ slider-page ]
[ slider-length 1 max ]
bi / 1 min ;
2007-09-20 18:09:08 -04:00
: thumb-dim ( slider -- h )
[
2009-02-12 02:40:18 -05:00
[ visible-portion ] [ elevator-length ] bi *
min-thumb-dim max
]
2009-02-12 02:40:18 -05:00
[ elevator-length ] bi min ;
2007-09-20 18:09:08 -04:00
: slider-scale ( slider -- n )
2015-09-08 19:15:10 -04:00
! A scaling factor such that if x is a slider co-ordinate,
! x*n is the screen position of the thumb, and conversely
! for x/n. The '1 max' calls avoid division by zero.
[ [ elevator-length ] [ thumb-dim ] bi - 1 max ]
[ slider-length* 1 max ]
bi / ;
2007-09-20 18:09:08 -04:00
: slider>screen ( m slider -- n ) slider-scale * ;
: screen>slider ( m slider -- n ) slider-scale / ;
2007-09-20 18:09:08 -04:00
2008-08-31 02:42:30 -04:00
M: slider model-changed nip elevator>> relayout-1 ;
2007-09-20 18:09:08 -04:00
2009-02-12 02:40:18 -05:00
TUPLE: thumb < track ;
2007-09-20 18:09:08 -04:00
: begin-drag ( thumb -- )
2008-09-27 17:45:20 -04:00
find-slider dup slider-value >>saved drop ;
2007-09-20 18:09:08 -04:00
: do-drag ( thumb -- )
2009-02-12 02:40:18 -05:00
find-slider {
[ orientation>> drag-loc v. ]
[ screen>slider ]
[ saved>> + ]
[ model>> set-range-value ]
} cleave ;
2007-09-20 18:09:08 -04:00
thumb H{
{ T{ button-down } [ begin-drag ] }
{ T{ button-up } [ drop ] }
{ T{ drag } [ do-drag ] }
} set-gestures
2009-02-12 02:40:18 -05:00
CONSTANT: horizontal-thumb-tiles
{
{ "horizontal-scroller-handle-left" f }
{ "horizontal-scroller-handle-middle" 1/2 }
{ "horizontal-scroller-handle-grip" f }
{ "horizontal-scroller-handle-middle" 1/2 }
{ "horizontal-scroller-handle-right" f }
}
CONSTANT: vertical-thumb-tiles
{
{ "vertical-scroller-handle-top" f }
{ "vertical-scroller-handle-middle" 1/2 }
{ "vertical-scroller-handle-grip" f }
{ "vertical-scroller-handle-middle" 1/2 }
{ "vertical-scroller-handle-bottom" f }
}
: build-thumb ( thumb -- thumb )
dup orientation>> {
{ horizontal [ horizontal-thumb-tiles ] }
{ vertical [ vertical-thumb-tiles ] }
} case
[ [ theme-image <icon> ] dip track-add ] assoc-each ;
: <thumb> ( orientation -- thumb )
thumb new-track
0 >>fill
1/2 >>align
build-thumb
t >>root? ;
2007-09-20 18:09:08 -04:00
: compute-direction ( elevator -- -1/1 )
[ hand-click-rel ] [ find-slider ] bi
[ orientation>> v. ]
[ screen>slider ]
[ slider-value - sgn ]
tri ;
2007-09-20 18:09:08 -04:00
: elevator-hold ( elevator -- )
[ direction>> ] [ find-slider ] bi slide-by-page ;
2007-09-20 18:09:08 -04:00
: elevator-click ( elevator -- )
dup compute-direction >>direction
2007-09-20 18:09:08 -04:00
elevator-hold ;
elevator H{
{ T{ drag } [ elevator-hold ] }
{ T{ button-down } [ elevator-click ] }
} set-gestures
: <elevator> ( vector -- elevator )
elevator new
2009-02-12 02:40:18 -05:00
swap >>orientation ;
2007-09-20 18:09:08 -04:00
: thumb-loc ( slider -- loc )
[ slider-value ]
[ slider-min - ]
[ slider>screen elevator-padding + ] tri ;
2007-09-20 18:09:08 -04:00
2009-02-12 02:40:18 -05:00
: layout-thumb-loc ( thumb slider -- )
2011-10-15 22:19:44 -04:00
[ thumb-loc ] [ orientation>> ] bi n*v vfloor >>loc drop ;
2007-09-20 18:09:08 -04:00
2009-02-12 02:40:18 -05:00
: layout-thumb-dim ( thumb slider -- )
[ dim>> ] [ thumb-dim ] [ orientation>> ] tri [ n*v ] keep set-axis
2011-10-15 22:19:44 -04:00
vceiling >>dim drop ;
2007-09-20 18:09:08 -04:00
: slider-enabled? ( slider -- ? )
visible-portion 1 = not ;
2007-09-20 18:09:08 -04:00
: layout-thumb ( slider -- )
2009-02-12 02:40:18 -05:00
[ thumb>> ] keep
[ slider-enabled? >>visible? drop ]
2009-02-12 02:40:18 -05:00
[ layout-thumb-loc ]
[ layout-thumb-dim ]
2tri ;
2007-09-20 18:09:08 -04:00
M: elevator layout*
find-slider layout-thumb ;
2009-02-12 02:40:18 -05:00
: add-thumb-to-elevator ( object -- object )
[ elevator>> ] [ thumb>> ] bi add-gadget ;
2007-09-20 18:09:08 -04:00
2009-02-12 02:40:18 -05:00
: <slide-button-pen> ( orientation left right -- pen )
[ horizontal = ] 2dip ?
[ f f ] [ theme-image <image-pen> f f ] bi* <button-pen> ;
2007-09-20 18:09:08 -04:00
2009-02-12 02:40:18 -05:00
TUPLE: slide-button < repeat-button ;
2007-09-20 18:09:08 -04:00
2009-02-12 02:40:18 -05:00
: <slide-button> ( orientation amount left right -- button )
[ swap ] 2dip
[
[ <gadget> ] dip
'[ _ swap find-slider slide-by-line ]
slide-button new-button
] 3dip
<slide-button-pen> >>interior ;
M: slide-button pref-dim* dup interior>> pen-pref-dim ;
: <up-button> ( orientation -- button )
-1
"horizontal-scroller-leftarrow-clicked"
"vertical-scroller-uparrow-clicked"
<slide-button> ;
: <down-button> ( orientation -- button )
1
"horizontal-scroller-rightarrow-clicked"
"vertical-scroller-downarrow-clicked"
<slide-button> ;
TUPLE: slider-pen enabled disabled ;
2009-02-12 02:40:18 -05:00
: <slider-pen> ( orientation -- pen )
{
{ horizontal [
"horizontal-scroller-left" theme-image
"horizontal-scroller-middle" theme-image
"horizontal-scroller-right" theme-image
"horizontal-scroller-right-disabled" theme-image
2009-02-12 02:40:18 -05:00
] }
{ vertical [
"vertical-scroller-top" theme-image
"vertical-scroller-middle" theme-image
"vertical-scroller-bottom" theme-image
"vertical-scroller-bottom-disabled" theme-image
2009-02-12 02:40:18 -05:00
] }
} case
[ f f <tile-pen> ] bi-curry@ 2bi slider-pen boa ;
: current-pen ( slider pen -- pen )
[ slider-enabled? ] [ [ enabled>> ] [ disabled>> ] bi ] bi* ? ;
M: slider-pen draw-interior
dupd current-pen draw-interior ;
M: slider-pen draw-boundary
dupd current-pen draw-boundary ;
M: slider-pen pen-pref-dim
enabled>> pen-pref-dim ;
2007-09-20 18:09:08 -04:00
M: slider pref-dim*
[ dup slider-enabled? [ dup interior>> pen-pref-dim ] [ drop { 0 0 } ] if ]
2016-04-23 04:47:52 -04:00
[ drop { 100 100 } ]
[ orientation>> ] tri set-axis ;
2009-02-12 02:40:18 -05:00
PRIVATE>
: <slider> ( range orientation -- slider )
slider new-track
swap >>model
16 >>line
2009-02-12 02:40:18 -05:00
dup orientation>> {
[ <slider-pen> >>interior ]
2009-02-12 02:40:18 -05:00
[ <thumb> >>thumb ]
[ <elevator> >>elevator ]
[ drop dup add-thumb-to-elevator 1 track-add ]
[ <up-button> f track-add ]
[ <down-button> f track-add ]
[ drop <gadget> { 1 1 } >>dim f track-add ]
} cleave ;