1 ! Copyright (C) 2006, 2009 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: arrays assocs io kernel math models namespaces make dlists
4 deques sequences threads sequences words continuations init call
5 combinators hashtables concurrency.flags sets accessors calendar fry
6 destructors ui.gadgets ui.gadgets.private ui.gadgets.worlds
7 ui.gadgets.tracks ui.gestures ui.backend ui.render ui.text
13 ! Assoc mapping aliens to gadgets
16 : window ( handle -- world ) windows get-global at ;
18 : window-focus ( handle -- gadget ) window world-focus ;
20 : register-window ( world handle -- )
21 #! Add the new window just below the topmost window. Why?
22 #! So that if the new window doesn't actually receive focus
23 #! (eg, we're using focus follows mouse and the mouse is not
24 #! in the new window when it appears) Factor doesn't get
25 #! confused and send workspace operations to the new window,
27 swap 2array windows get-global push
28 windows get-global dup length 1 >
29 [ [ length 1- dup 1- ] keep exchange ] [ drop ] if ;
31 : unregister-window ( handle -- )
32 windows global [ [ first = not ] with filter ] change-at ;
34 : raised-window ( world -- )
36 [ [ second eq? ] with find drop ] keep
37 [ nth ] [ delete-nth ] [ nip ] 2tri push ;
39 : focus-gestures ( new old -- )
40 drop-prefix <reversed>
41 lose-focus swap each-gesture
42 gain-focus swap each-gesture ;
44 : focus-world ( world -- )
47 focus-path f focus-gestures ;
49 : unfocus-world ( world -- )
51 focus-path f swap focus-gestures ;
55 [ [ title>> ] keep set-title ]
56 [ request-focus ] tri ;
58 : reset-world ( world -- )
59 #! This is used when a window is being closed, but also
60 #! when restoring saved worlds on image startup.
61 f >>handle unfocus-world ;
63 : (ungraft-world) ( world -- )
65 [ handle>> select-gl-context ]
66 [ text-handle>> dispose ]
67 [ images>> [ dispose ] when* ]
68 [ hand-clicked close-global ]
69 [ hand-gadget close-global ]
74 [ handle>> (close-window) ]
78 <dlist> \ graft-queue set-global
79 <dlist> \ layout-queue set-global
80 <dlist> \ gesture-queue set-global
81 V{ } clone windows set-global ;
83 : restore-gadget-later ( gadget -- )
87 { { t t } [ { f f } >>graft-state ] }
88 { { t f } [ dup unqueue-graft { f f } >>graft-state ] }
91 : restore-gadget ( gadget -- )
92 dup restore-gadget-later
93 children>> [ restore-gadget ] each ;
95 : restore-world ( world -- )
98 [ init-text-rendering ]
103 : update-hand ( world -- )
104 dup hand-world get-global eq?
105 [ hand-loc get-global swap move-hand ] [ drop ] if ;
107 : layout-queued ( -- seq )
111 dup layout find-world [ , ] when*
115 : redraw-worlds ( seq -- )
116 [ dup update-hand draw-world ] each ;
118 : send-queued-gestures ( -- )
119 gesture-queue [ send-queued-gesture notify-queued ] slurp-deque ;
127 ] [ ui-error ] recover ;
131 : ui-running ( quot -- )
132 t \ ui-running set-global
133 [ f \ ui-running set-global ] [ ] cleanup ; inline
137 : find-window ( quot -- world )
139 [ gadget-child swap call ] with find-last nip ; inline
141 : ui-running? ( -- ? )
142 \ ui-running get-global ;
146 : update-ui-loop ( -- )
147 [ ui-running? ui-thread get-global self eq? and ]
148 [ ui-notify-flag get lower-flag update-ui ]
151 : start-ui-thread ( -- )
152 [ self ui-thread set-global update-ui-loop ]
153 "UI update" spawn drop ;
155 : start-ui ( quot -- )
156 call notify-ui-thread start-ui-thread ;
158 : restore-windows ( -- )
160 windows get [ values ] [ delete-all ] bi
161 [ restore-world ] each
165 : restore-windows? ( -- ? )
166 windows get empty? not ;
170 : open-world-window ( world -- )
171 dup pref-dim >>dim dup relayout graft ;
173 : open-window ( gadget title -- )
174 f <world> open-world-window ;
176 : set-fullscreen? ( ? gadget -- )
177 find-world set-fullscreen* ;
179 : fullscreen? ( gadget -- ? )
180 find-world fullscreen* ;
182 : raise-window ( gadget -- )
183 find-world raise-window* ;
185 HOOK: close-window ui-backend ( gadget -- )
187 M: object close-window
188 find-world [ ungraft ] when* ;
191 f \ ui-running set-global
192 <flag> ui-notify-flag set-global
195 : with-ui ( quot -- )
196 ui-running? [ call ] [ '[ init-ui @ ] (with-ui) ] if ;
198 HOOK: beep ui-backend ( -- )