1 ! Copyright (C) 2006, 2007 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: arrays assocs io kernel math models namespaces
4 prettyprint dlists dequeues sequences threads sequences words
5 debugger ui.gadgets ui.gadgets.worlds ui.gadgets.tracks
6 ui.gestures ui.backend ui.render continuations init combinators
7 hashtables concurrency.flags sets accessors ;
10 ! Assoc mapping aliens to gadgets
13 SYMBOL: stop-after-last-window?
15 : event-loop? ( -- ? )
17 { [ stop-after-last-window? get not ] [ t ] }
18 { [ graft-queue dequeue-empty? not ] [ t ] }
19 { [ windows get-global empty? not ] [ t ] }
23 : event-loop ( -- ) [ event-loop? ] [ do-events ] [ ] while ;
25 : window ( handle -- world ) windows get-global at ;
27 : window-focus ( handle -- gadget ) window world-focus ;
29 : register-window ( world handle -- )
30 #! Add the new window just below the topmost window. Why?
31 #! So that if the new window doesn't actually receive focus
32 #! (eg, we're using focus follows mouse and the mouse is not
33 #! in the new window when it appears) Factor doesn't get
34 #! confused and send workspace operations to the new window,
36 swap 2array windows get-global push
37 windows get-global dup length 1 >
38 [ [ length 1- dup 1- ] keep exchange ] [ drop ] if ;
40 : unregister-window ( handle -- )
41 windows global [ [ first = not ] with filter ] change-at ;
43 : raised-window ( world -- )
45 [ [ second eq? ] with find drop ] keep
46 [ nth ] [ delete-nth ] [ nip ] 2tri push ;
48 : focus-gestures ( new old -- )
49 drop-prefix <reversed>
50 T{ lose-focus } swap each-gesture
51 T{ gain-focus } swap each-gesture ;
53 : focus-world ( world -- )
54 t over set-world-focused?
56 focus-path f focus-gestures ;
58 : unfocus-world ( world -- )
59 f over set-world-focused?
60 focus-path f swap focus-gestures ;
64 dup world-title over set-title
67 : reset-world ( world -- )
68 #! This is used when a window is being closed, but also
69 #! when restoring saved worlds on image startup.
70 dup world-fonts clear-assoc
72 f swap set-world-handle ;
76 dup hand-clicked close-global
77 dup hand-gadget close-global
78 dup world-handle (close-window)
81 : find-window ( quot -- world )
83 [ gadget-child swap call ] with find-last nip ; inline
88 <dlist> \ graft-queue set-global
89 <dlist> \ layout-queue set-global
90 V{ } clone windows set-global ;
92 : restore-gadget-later ( gadget -- )
93 dup gadget-graft-state {
97 { f f } over set-gadget-graft-state
101 { f f } over set-gadget-graft-state
105 : restore-gadget ( gadget -- )
106 dup restore-gadget-later
107 gadget-children [ restore-gadget ] each ;
109 : restore-world ( world -- )
110 dup reset-world restore-gadget ;
112 : restore-windows ( -- )
113 windows get [ values ] keep delete-all
114 [ restore-world ] each
117 : restore-windows? ( -- ? )
118 windows get empty? not ;
120 : update-hand ( world -- )
121 dup hand-world get-global eq?
122 [ hand-loc get-global swap move-hand ] [ drop ] if ;
124 : layout-queued ( -- seq )
128 dup layout find-world [ , ] when*
132 : redraw-worlds ( seq -- )
133 [ dup update-hand draw-world ] each ;
135 : notify ( gadget -- )
136 dup gadget-graft-state
137 dup first { f f } { t t } ?
138 pick set-gadget-graft-state {
139 { { f t } [ dup activate-control graft* ] }
140 { { t f } [ dup deactivate-control ungraft* ] }
143 : notify-queued ( -- )
144 graft-queue [ notify ] slurp-dequeue ;
147 [ notify-queued layout-queued redraw-worlds ] assert-depth ;
152 : ui-try ( quot -- ) [ ui-error ] recover ;
156 : ui-running ( quot -- )
157 t \ ui-running set-global
158 [ f \ ui-running set-global ] [ ] cleanup ; inline
160 : ui-running? ( -- ? )
161 \ ui-running get-global ;
163 : update-ui-loop ( -- )
164 ui-running? ui-thread get-global self eq? and [
165 ui-notify-flag get lower-flag
170 : start-ui-thread ( -- )
171 [ self ui-thread set-global update-ui-loop ]
172 "UI update" spawn drop ;
174 : open-world-window ( world -- )
175 dup pref-dim over (>>dim) dup relayout graft ;
177 : open-window ( gadget title -- )
178 f <world> open-world-window ;
180 : set-fullscreen? ( ? gadget -- )
181 find-world set-fullscreen* ;
183 : fullscreen? ( gadget -- ? )
184 find-world fullscreen* ;
186 : raise-window ( gadget -- )
187 find-world raise-window* ;
189 HOOK: close-window ui-backend ( gadget -- )
191 M: object close-window
192 find-world [ ungraft ] when* ;
198 init-ui ui-hook get call
200 notify-ui-thread start-ui-thread ;
203 f \ ui-running set-global
204 <flag> ui-notify-flag set-global
207 HOOK: ui ui-backend ( -- )
211 : with-ui ( quot -- )
218 stop-after-last-window? on