1 ! Copyright (C) 2006, 2007 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: ui.commands ui.gestures ui.render ui.gadgets
4 ui.gadgets.controls ui.gadgets.labels ui.gadgets.scrollers
5 kernel sequences models opengl math namespaces
6 ui.gadgets.presentations ui.gadgets.viewports ui.gadgets.packs
10 TUPLE: list index presenter color hook ;
12 : list-theme ( list -- )
13 { 0.8 0.8 1.0 1.0 } swap set-list-color ;
15 : <list> ( hook presenter model -- gadget )
16 <filled-pile> list construct-control
17 [ set-list-presenter ] keep
18 [ set-list-hook ] keep
22 : calc-bounded-index ( n list -- m )
23 control-value length 1- min 0 max ;
25 : bound-index ( list -- )
26 dup list-index over calc-bounded-index
29 : list-presentation-hook ( list -- quot )
30 list-hook [ [ [ list? ] is? ] find-parent ] swap append ;
32 : <list-presentation> ( hook elt presenter -- gadget )
34 [ set-presentation-hook ] keep
37 : <list-items> ( list -- seq )
38 dup list-presentation-hook
41 >r 2dup r> swap <list-presentation>
46 dup <list-items> over add-gadgets
49 : selected-rect ( list -- rect )
50 dup list-index swap gadget-children ?nth ;
54 dup list-color gl-color
55 selected-rect [ rect-extent gl-fill-rect ] when*
58 M: list focusable-child* drop t ;
60 : list-value ( list -- object )
61 dup list-index swap control-value ?nth ;
63 : scroll>selected ( list -- )
64 #! We change the rectangle's width to zero to avoid
66 [ selected-rect rect-bounds { 0 1 } v* <rect> ] keep
69 : list-empty? ( list -- ? ) control-value empty? ;
71 : select-index ( n list -- )
75 [ control-value length rem ] keep
76 [ set-list-index ] keep
81 : select-previous ( list -- )
82 dup list-index 1- swap select-index ;
84 : select-next ( list -- )
85 dup list-index 1+ swap select-index ;
87 : invoke-value-action ( list -- )
91 dup list-index swap nth-gadget invoke-secondary
94 : select-gadget ( gadget list -- )
95 swap over gadget-children index
96 [ swap select-index ] [ drop ] if* ;
98 : clamp-loc ( point max -- point )
101 : select-at ( point list -- )
102 [ rect-dim clamp-loc ] keep
106 : list-page ( list vec -- )
107 >r dup selected-rect rect-bounds 2 v/n v+
108 over visible-dim r> v* v+ swap select-at ;
110 : list-page-up ( list -- ) { 0 -1 } list-page ;
112 : list-page-down ( list -- ) { 0 1 } list-page ;
114 list "keyboard-navigation" "Lists can be navigated from the keyboard." {
115 { T{ button-down } request-focus }
116 { T{ key-down f f "UP" } select-previous }
117 { T{ key-down f f "DOWN" } select-next }
118 { T{ key-down f f "PAGE_UP" } list-page-up }
119 { T{ key-down f f "PAGE_DOWN" } list-page-down }
120 { T{ key-down f f "RET" } invoke-value-action }