1 ! Copyright (C) 2005, 2007 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors arrays ui.gestures ui.gadgets ui.gadgets.buttons
4 ui.gadgets.frames ui.gadgets.grids math.order
5 ui.gadgets.theme ui.render kernel math namespaces sequences
6 vectors models models.range math.vectors math.functions
7 quotations colors math.geometry.rect fry ;
10 TUPLE: elevator < gadget direction ;
12 : find-elevator ( gadget -- elevator/f ) [ elevator? ] find-parent ;
14 TUPLE: slider < frame elevator thumb saved line ;
16 : find-slider ( gadget -- slider/f ) [ slider? ] find-parent ;
18 : elevator-length ( slider -- n )
19 [ elevator>> dim>> ] [ orientation>> ] bi v. ;
23 : slider-value ( gadget -- n ) model>> range-value >fixnum ;
24 : slider-page ( gadget -- n ) model>> range-page-value ;
25 : slider-max ( gadget -- n ) model>> range-max-value ;
26 : slider-max* ( gadget -- n ) model>> range-max-value* ;
28 : thumb-dim ( slider -- h )
30 [ [ slider-page ] [ slider-max 1 max ] bi / 1 min ]
31 [ elevator-length ] bi * min-thumb-dim max
33 [ [ elevator>> dim>> ] [ orientation>> ] bi v. ] bi min ;
35 : slider-scale ( slider -- n )
36 #! A scaling factor such that if x is a slider co-ordinate,
37 #! x*n is the screen position of the thumb, and conversely
38 #! for x/n. The '1 max' calls avoid division by zero.
39 dup elevator-length over thumb-dim - 1 max
40 swap slider-max* 1 max / ;
42 : slider>screen ( m scale -- n ) slider-scale * ;
43 : screen>slider ( m scale -- n ) slider-scale / ;
45 M: slider model-changed nip elevator>> relayout-1 ;
47 TUPLE: thumb < gadget ;
49 : begin-drag ( thumb -- )
50 find-slider dup slider-value >>saved drop ;
52 : do-drag ( thumb -- )
53 find-slider drag-loc over orientation>> v.
54 over screen>slider swap [ saved>> + ] keep
55 model>> set-range-value ;
58 { T{ button-down } [ begin-drag ] }
59 { T{ button-up } [ drop ] }
60 { T{ drag } [ do-drag ] }
63 : thumb-theme ( thumb -- thumb )
64 plain-gradient >>interior
65 faint-boundary ; inline
67 : <thumb> ( vector -- thumb )
73 : slide-by ( amount slider -- ) model>> move-by ;
75 : slide-by-page ( amount slider -- ) model>> move-by-page ;
77 : compute-direction ( elevator -- -1/1 )
78 dup find-slider swap hand-click-rel
81 swap slider-value - sgn ;
83 : elevator-hold ( elevator -- )
84 dup direction>> swap find-slider slide-by-page ;
86 : elevator-click ( elevator -- )
87 dup compute-direction >>direction
91 { T{ drag } [ elevator-hold ] }
92 { T{ button-down } [ elevator-click ] }
95 : <elevator> ( vector -- elevator )
98 lowered-gradient >>interior ;
100 : (layout-thumb) ( slider n -- n thumb )
101 over orientation>> n*v swap thumb>> ;
103 : thumb-loc ( slider -- loc )
104 dup slider-value swap slider>screen ;
106 : layout-thumb-loc ( slider -- )
107 dup thumb-loc (layout-thumb)
108 [ [ floor ] map ] dip (>>loc) ;
110 : layout-thumb-dim ( slider -- )
111 dup dup thumb-dim (layout-thumb)
113 [ [ rect-dim ] dip ] [ drop orientation>> ] 2bi set-axis
117 : layout-thumb ( slider -- )
118 dup layout-thumb-loc layout-thumb-dim ;
121 find-slider layout-thumb ;
123 : slide-by-line ( amount slider -- ) [ line>> * ] keep slide-by ;
125 : <slide-button> ( vector polygon amount -- button )
126 [ gray swap <polygon-gadget> ] dip
127 '[ _ swap find-slider slide-by-line ] <repeat-button>
130 : elevator, ( gadget orientation -- gadget )
131 tuck <elevator> >>elevator
133 dup elevator>> over thumb>> add-gadget
136 : <left-button> ( -- button ) { 0 1 } arrow-left -1 <slide-button> ;
137 : <right-button> ( -- button ) { 0 1 } arrow-right 1 <slide-button> ;
138 : <up-button> ( -- button ) { 1 0 } arrow-up -1 <slide-button> ;
139 : <down-button> ( -- button ) { 1 0 } arrow-down 1 <slide-button> ;
141 : <slider> ( range orientation -- slider )
147 : <x-slider> ( range -- slider )
149 <left-button> @left grid-add
151 <right-button> @right grid-add ;
153 : <y-slider> ( range -- slider )
155 <up-button> @top grid-add
157 <down-button> @bottom grid-add ;
161 swap orientation>> [ 40 v*n ] keep