1 ! Copyright (C) 2006, 2008 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors ui.commands ui.gestures ui.render ui.gadgets
4 ui.gadgets.labels ui.gadgets.scrollers
5 kernel sequences models opengl math math.order namespaces
6 ui.gadgets.presentations ui.gadgets.viewports ui.gadgets.packs
7 math.vectors classes.tuple math.geometry.rect colors ;
11 TUPLE: list < pack index presenter color hook ;
13 : list-theme ( list -- list )
14 T{ rgba f 0.8 0.8 1.0 1.0 } >>color ; inline
16 : <list> ( hook presenter model -- gadget )
26 : calc-bounded-index ( n list -- m )
27 control-value length 1- min 0 max ;
29 : bound-index ( list -- )
30 dup index>> over calc-bounded-index >>index drop ;
32 : list-presentation-hook ( list -- quot )
33 hook>> [ [ list? ] find-parent ] prepend ;
35 : <list-presentation> ( hook elt presenter -- gadget )
36 keep >r >label text-theme r>
40 : <list-items> ( list -- seq )
41 [ list-presentation-hook ]
45 >r 2dup r> swap <list-presentation>
51 dup <list-items> add-gadgets
54 : selected-rect ( list -- rect )
55 dup index>> swap children>> ?nth ;
60 selected-rect [ rect-extent gl-fill-rect ] when*
63 M: list focusable-child* drop t ;
65 : list-value ( list -- object )
66 dup index>> swap control-value ?nth ;
68 : scroll>selected ( list -- )
69 #! We change the rectangle's width to zero to avoid
71 [ selected-rect rect-bounds { 0 1 } v* <rect> ] keep
74 : list-empty? ( list -- ? ) control-value empty? ;
76 : select-index ( n list -- )
80 [ control-value length rem ] keep
86 : select-previous ( list -- )
87 dup index>> 1- swap select-index ;
89 : select-next ( list -- )
90 dup index>> 1+ swap select-index ;
92 : invoke-value-action ( list -- )
96 dup index>> swap nth-gadget invoke-secondary
99 : select-gadget ( gadget list -- )
100 swap over children>> index
101 [ swap select-index ] [ drop ] if* ;
103 : clamp-loc ( point max -- point )
106 : select-at ( point list -- )
107 [ rect-dim clamp-loc ] keep
111 : list-page ( list vec -- )
112 >r dup selected-rect rect-bounds 2 v/n v+
113 over visible-dim r> v* v+ swap select-at ;
115 : list-page-up ( list -- ) { 0 -1 } list-page ;
117 : list-page-down ( list -- ) { 0 1 } list-page ;
119 list "keyboard-navigation" "Lists can be navigated from the keyboard." {
120 { T{ button-down } request-focus }
121 { T{ key-down f f "UP" } select-previous }
122 { T{ key-down f f "DOWN" } select-next }
123 { T{ key-down f f "PAGE_UP" } list-page-up }
124 { T{ key-down f f "PAGE_DOWN" } list-page-down }
125 { T{ key-down f f "RET" } invoke-value-action }