1 ! Copyright (C) 2006 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
4 USING: arrays errors gadgets gadgets-buttons gadgets-frames
5 gadgets-grids gadgets-labels gadgets-panes gadgets-presentations
6 gadgets-scrolling gadgets-theme gadgets-viewports generic
7 hashtables io kernel math models namespaces prettyprint queues
8 sequences test threads help sequences words ;
10 ! Assoc mapping aliens to gadgets
13 : window ( handle -- world ) windows get-global assoc ;
15 : window-focus ( handle -- gadget ) window world-focus ;
17 : register-window ( world handle -- )
18 swap 2array windows get-global push ;
20 : unregister-window ( handle -- )
22 [ first = not ] subset-with
25 : raised-window ( world -- )
26 windows get-global [ second eq? ] find-with drop
27 windows get-global [ length 1- ] keep exchange ;
29 : update-hand ( gadget -- )
31 dup hand-world get-global eq?
32 [ hand-loc get-global swap move-hand ] [ drop ] if
35 : post-layout ( gadget -- )
36 find-world [ dup world-handle set ] when* ;
38 : layout-queued ( -- )
39 invalid dup queue-empty? [
42 deque dup layout post-layout layout-queued
46 <queue> \ invalid set-global
47 V{ } clone windows set-global ;
52 [ layout-queued ] make-hash hash-values [
54 dup world-handle [ dup draw-world ] when
60 TUPLE: titled-gadget title ;
62 M: titled-gadget gadget-title titled-gadget-title ;
64 M: titled-gadget focusable-child* gadget-child ;
66 C: titled-gadget ( gadget title -- )
67 [ set-titled-gadget-title ] keep
68 { { f f f @center } } make-frame* ;
70 : open-window ( world -- )
71 dup pref-dim over set-gadget-dim
72 dup open-window* draw-world ;
74 : open-titled-window ( gadget title -- )
75 <model> <titled-gadget> <world> open-window ;
77 : find-window ( quot -- world )
78 windows get [ second ] map
79 [ world-gadget swap call ] find-last-with nip ; inline
81 : start-world ( world -- )
84 world-gadget request-focus ;
86 : close-global ( world global -- )
87 dup get-global find-world rot eq?
88 [ f swap set-global ] [ drop ] if ;
90 : focus-world ( world -- )
91 #! Sent when native window receives focus
92 t over set-world-focused?
94 focused-ancestors f focus-gestures ;
96 : unfocus-world ( world -- )
97 #! Sent when native window loses focus.
98 f over set-world-focused?
99 focused-ancestors f swap focus-gestures ;
101 : reset-world ( world -- )
104 f over set-world-focus
105 f over set-world-handle
106 world-fonts clear-hash ;
108 : close-world ( world -- )
109 dup hand-clicked close-global
110 dup hand-gadget close-global
114 : restore-windows ( -- )
115 windows get [ [ second ] map ] keep delete-all
116 [ dup reset-world open-window* ] each
119 : restore-windows? ( -- ? )
120 windows get [ empty? not ] [ f ] if* ;
122 : <toolbar> ( target classes -- toolbar )
123 [ commands "Toolbar" swap hash ] map concat
124 [ <command-presentation> ] map-with
127 : command-description ( command -- element )
128 dup command-name swap command-gesture gesture>string
131 : command-table. ( commands group -- )
133 [ command-gesture key-down? ] subset
134 [ command-description ] map
135 { "Command" "Shortcut" } add* $table ;
137 : commands. ( hash -- )
139 [ [ first ] 2apply <=> ] sort
140 [ first2 swap command-table. ] each ;
142 : $commands ( elt -- )
143 dup array? [ first ] when commands commands. ;
145 TUPLE: labelled-gadget content ;
147 C: labelled-gadget ( gadget title -- gadget )
149 { [ <label> dup reverse-video-theme ] f f @top }
150 { f set-labelled-gadget-content f @center }
153 M: labelled-gadget focusable-child* labelled-gadget-content ;
155 : <labelled-pane> ( model quot title -- gadget )
156 >r <pane-control> <scroller> r> <labelled-gadget> ;
158 : pane-window ( quot title -- )
159 >r make-pane <scroller> r> open-titled-window ;
161 : error-window ( error -- )
162 [ print-error ] "Error" pane-window ;
165 [ error-window ] recover ;
167 TUPLE: world-error world ;
169 C: world-error ( error world -- error )
170 [ set-world-error-world ] keep
171 [ set-delegate ] keep ;
173 M: world-error error.
174 "An error occurred while drawing the world " write
175 dup world-error-world pprint-short "." print
176 "This world has been deactivated to prevent cascading errors." print
179 : draw-world? ( world -- ? )
180 #! We don't draw deactivated worlds, or those with 0 size.
181 #! On Windows, the latter case results in GL errors.
182 dup world-active? swap rect-dim [ zero? not ] all? and ;
184 : draw-world ( world -- )
190 over <world-error> error-window
191 f over set-world-active?