-
-
Notifications
You must be signed in to change notification settings - Fork 71
/
moredialogs.rkt
400 lines (374 loc) · 17.5 KB
/
moredialogs.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
#lang racket/base
(require racket/class
(prefix-in wx: "kernel.rkt")
(prefix-in wx: racket/snip/private/style)
"lock.rkt"
"const.rkt"
"check.rkt"
"wx.rkt"
"helper.rkt"
"mrtop.rkt"
"mrcanvas.rkt"
"mritem.rkt"
"mrpanel.rkt"
"mrtextfield.rkt")
(provide get-ps-setup-from-user
get-page-setup-from-user
can-get-page-setup-from-user?
get-text-from-user
get-choices-from-user
get-color-from-user)
(define (number->string* n)
(let ([s (number->string n)])
(regexp-replace #rx"[.]([0-9][0-9][0-9])[0-9]*$"
s
".\\1")))
(define get-ps-setup-from-user
(case-lambda
[() (get-ps-setup-from-user #f #f #f null)]
[(message) (get-ps-setup-from-user message #f #f null)]
[(message parent) (get-ps-setup-from-user message parent #f null)]
[(message parent pss) (get-ps-setup-from-user message parent pss null)]
[(message parent pss-in style)
(define _
(begin
;; Calls from C++ have wrong kind of window:
(when (is-a? parent wx:window%)
(set! parent (as-entry (lambda () (wx->mred parent)))))
(check-label-string/false 'get-ps-setup-from-user message)
(check-top-level-parent/false 'get-ps-setup-from-user parent)
(check-instance 'get-ps-setup-from-user wx:ps-setup% 'ps-setup% #t pss-in)
(check-style 'get-ps-setup-from-user #f null style)))
(define bad-fields null)
(define number-callback
(lambda (f ev)
(let ([e (send f get-editor)]
[ok? (real? (string->number (send f get-value)))])
(send e change-style
(send (make-object wx:style-delta%)
set-delta-background
(if ok? "white" "yellow"))
0 (send e last-position))
(set! bad-fields (remq f bad-fields))
(unless ok?
(set! bad-fields (cons f bad-fields)))
(send ok enable (null? bad-fields)))))
(define pss (or pss-in (wx:current-ps-setup)))
(define f (make-object dialog% "PostScript Setup" parent))
(define papers
'("A4 210 x 297 mm" "A3 297 x 420 mm" "Letter 8 1/2 x 11 in" "Legal 8 1/2 x 14 in"))
(define p (make-object horizontal-pane% f))
(define paper (make-object choice% #f papers p void))
(define _0 (make-object vertical-pane% p))
(define-values (ok cancel)
(ok-cancel
(lambda () (make-object button% "OK" p (lambda (b e) (done #t)) '(border)))
(lambda () (make-object button% "Cancel" p (lambda (b e) (done #f))))))
(define unix? (eq? (system-type) 'unix))
(define dp (make-object horizontal-pane% f))
(define orientation (make-object radio-box% "Orientation:" '("Portrait" "Landscape") dp void))
(define destination (and unix? (make-object radio-box% "Destination:"
'("Printer" "Preview" "File") dp void)))
(define ssp (make-object horizontal-pane% f))
(define sp (make-object vertical-pane% ssp))
(define def-scale "0100.000")
(define def-offset "0000.000")
(define def-margin "0016.000")
(define xscale (make-object text-field% "Horizontal Scale:" sp number-callback def-scale))
(define xoffset (make-object text-field% "Horizontal Translation:" sp number-callback def-offset))
(define xmargin (make-object text-field% "Horizontal Margin:" sp number-callback def-margin))
(define sp2 (make-object vertical-pane% ssp))
(define yscale (make-object text-field% "Vertical Scale:" sp2 number-callback def-scale))
(define yoffset (make-object text-field% "Vertical Translation:" sp2 number-callback def-offset))
(define ymargin (make-object text-field% "Vertical Margin:" sp2 number-callback def-margin))
(define l2 (make-object check-box% "PostScript Level 2" f void))
(define cp (and unix? (make-object horizontal-pane% f)))
(define command (and unix? (make-object text-field% "Print Command:" cp void)))
(define vcommand (and unix? (make-object text-field% "Preview Command:" f void)))
(define ok? #f)
(define (done ?)
(send f show #f)
(set! ok? ?))
(define-values (xsb ysb xtb ytb xmb ymb)
(values (box 0) (box 0) (box 0) (box 0) (box 0) (box 0)))
(send paper set-selection (or (find-pos papers (send pss get-paper-name) equal?) 0))
(send orientation set-selection (if (eq? (send pss get-orientation) 'landscape) 1 0))
(when unix?
(send destination set-selection (case (send pss get-mode)
[(printer) 0] [(preview) 1] [(file) 2]))
(send command set-value (send pss get-command))
(send vcommand set-value (send pss get-preview-command)))
(send sp set-alignment 'right 'top)
(send sp2 set-alignment 'right 'top)
(send pss get-scaling xsb ysb)
(send xscale set-value (number->string* (unbox xsb)))
(send yscale set-value (number->string* (unbox ysb)))
(send pss get-translation xtb ytb)
(send xoffset set-value (number->string* (unbox xtb)))
(send yoffset set-value (number->string* (unbox ytb)))
(send pss get-margin xmb ymb)
(send xmargin set-value (number->string* (unbox xmb)))
(send ymargin set-value (number->string* (unbox ymb)))
(send xscale stretchable-width #f)
(send yscale stretchable-width #f)
(send xoffset stretchable-width #f)
(send yoffset stretchable-width #f)
(send xmargin stretchable-width #f)
(send ymargin stretchable-width #f)
(send l2 set-value (send pss get-level-2))
(send f set-alignment 'center 'top)
(map no-stretch (list f xscale yscale xoffset yoffset xmargin ymargin dp))
(send f center)
(send f show #t)
(if ok?
(let ([s (make-object wx:ps-setup%)]
[gv (lambda (c b)
(or (string->number (send c get-value)) (unbox b)))])
(send s set-paper-name (send paper get-string-selection))
(send s set-orientation (if (positive? (send orientation get-selection))
'landscape
'portrait))
(when unix?
(send s set-mode (case (send destination get-selection)
[(0) 'printer]
[(1) 'preview]
[(2) 'file])))
(send s set-scaling (gv xscale xsb) (gv yscale ysb))
(send s set-translation (gv xoffset xtb) (gv yoffset ytb))
(send s set-margin (gv xmargin xmb) (gv ymargin ymb))
(send s set-level-2 (send l2 get-value))
(when (eq? (system-type) 'unix)
(send s set-command (send command get-value))
(send s set-preview-command (send vcommand get-value)))
s)
#f)]))
(define get-page-setup-from-user
(case-lambda
[() (get-page-setup-from-user #f #f #f null)]
[(message) (get-page-setup-from-user message #f #f null)]
[(message parent) (get-page-setup-from-user message parent #f null)]
[(message parent pss) (get-page-setup-from-user message parent pss null)]
[(message parent pss-in style)
(check-label-string/false 'get-page-setup-from-user message)
(check-top-level-parent/false 'get-page-setup-from-user parent)
(check-instance 'get-page-setup-from-user wx:ps-setup% 'ps-setup% #t pss-in)
(check-style 'get-page-setup-from-user #f null style)
(and (wx:can-show-print-setup?)
(let ([s (make-object wx:ps-setup%)])
(send s copy-from (or pss-in (wx:current-ps-setup)))
(and (parameterize ([wx:current-ps-setup s])
(wx:show-print-setup (and parent (mred->wx parent))))
s)))]))
(define (can-get-page-setup-from-user?)
(wx:can-show-print-setup?))
(define (get-text-from-user title message
[parent #f]
[init-val ""]
[style null]
#:dialog-mixin [dialog-mixin values]
#:validate [validate (λ (x) #t)])
(check-label-string 'get-text-from-user title)
(check-label-string/false 'get-text-from-user message)
(check-top-level-parent/false 'get-text-from-user parent)
(check-string 'get-text-from-user init-val)
(check-style 'get-text-from-user #f '(password disallow-invalid) style)
(define f (make-object (dialog-mixin dialog%) title parent box-width))
(define ok? #f)
(define (done ?) (set! ok? ?) (send f show #f))
(define t (new text-field%
[label message]
[parent f]
[callback (λ (t e)
(cond
[(eq? (send e get-event-type) 'text-field-enter)
(when (send ok-button is-enabled?)
(done #t))]
[else (do-validation)]))]
[init-value init-val]
[style (list* 'single 'vertical-label
(if (memq 'password style)
'(password)
'()))]))
(define default-background (send t get-field-background))
(define (do-validation)
(define valid? (validate (send t get-value)))
(send t set-field-background
(if valid?
default-background
(send wx:the-color-database find-color "pink")))
(when (memq 'disallow-invalid style)
(send ok-button enable valid?)))
(define p (make-object horizontal-pane% f))
(send p set-alignment 'right 'center)
(send f stretchable-height #f)
(define-values (ok-button cancel-button)
(ok-cancel
(lambda () (make-object button% "OK" p (λ (b e) (done #t)) '(border)))
(lambda () (make-object button% "Cancel" p (λ (b e) (done #f))))))
(send (send t get-editor) select-all)
(send t focus)
(send f center)
(do-validation)
(send f show #t)
(and ok? (send t get-value)))
(define get-choices-from-user
(case-lambda
[(title message choices) (get-choices-from-user title message choices #f null '(single))]
[(title message choices parent) (get-choices-from-user title message choices parent null '(single))]
[(title message choices parent init-vals) (get-choices-from-user title message choices parent init-vals '(single))]
[(title message choices parent init-vals style)
(check-label-string 'get-choices-from-user title)
(check-label-string/false 'get-choices-from-user message)
(unless (and (list? choices) (andmap label-string? choices))
(raise-argument-error 'get-choices-from-user "(listof label-string?)" choices))
(check-top-level-parent/false 'get-choices-from-user parent)
(unless (and (list? init-vals) (andmap exact-nonnegative-integer? init-vals))
(raise-argument-error 'get-choices-from-user "(listof exact-nonnegative-integer?)" init-vals))
(check-style 'get-choices-from-user '(single multiple extended) null style)
(when (and (memq 'single style) (> (length init-vals) 1))
(raise-arguments-error 'get-choices-from-user
"multiple initial-selection indices provided with 'single style"
"indices" init-vals))
(let* ([f (make-object dialog% title parent box-width (min 300 (max 150 (* 14 (length choices)))))]
[ok-button #f]
[update-ok (lambda (l) (send ok-button enable (not (null? (send l get-selections)))))]
[ok? #f]
[done (lambda (?) (lambda (b e) (set! ok? ?) (send f show #f)))])
(let ([l (make-object list-box% message choices f
(lambda (l e)
(update-ok l)
(when (eq? (send e get-event-type) 'list-box-dclick)
((done #t) #f #f)))
(cons 'vertical-label style))]
[p (make-object horizontal-pane% f)])
(for-each (lambda (i)
(when (>= i (send l get-number))
(raise-arguments-error
'get-choices-from-user
"out of range;\n inital-selection list specifies an out-of-range index"
"index" i
"provided choices" (send l get-number)
"list..." init-vals))
(send l select i #t)) init-vals)
(send p set-alignment 'right 'center)
(send p stretchable-height #f)
(ok-cancel (lambda ()
(set! ok-button (make-object button% "OK" p (done #t) '(border))))
(lambda ()
(make-object button% "Cancel" p (done #f))))
(update-ok l)
(send f center)
(when (and (pair? init-vals)
((car init-vals) . > . 1))
;; Make sure initial selection is visible:
(send f reflow-container)
(send l set-first-visible-item (sub1 (car init-vals))))
(send f show #t)
(and ok? (send l get-selections))))]))
(define get-color-from-user
(case-lambda
[() (get-color-from-user #f #f #f null)]
[(message) (get-color-from-user message #f #f null)]
[(message parent) (get-color-from-user message parent #f null)]
[(message parent color) (get-color-from-user message parent color null)]
[(message parent in-color style)
(check-label-string/false 'get-color-from-user message)
(check-top-level-parent/false 'get-color-from-user parent)
(check-instance 'get-color-from-user wx:color% 'color% #t in-color)
(check-style 'get-color-from-user #f '(alpha) style)
(cond
[(eq? (wx:color-from-user-platform-mode) 'dialog)
(wx:get-color-from-user message (and parent (mred->wx parent)) in-color)]
[else
(define color (cond
[in-color
(if (member 'alpha style)
in-color
(make-object wx:color%
(send in-color red)
(send in-color green)
(send in-color blue)
1.0))]
[else (make-object wx:color% 0 0 0)]))
(define ok? #f)
(define f (make-object dialog% "Choose Color" parent))
(define (done ok) (lambda (b e) (set! ok? ok) (send f show #f)))
(define canvas (make-object (class canvas%
(define/override (on-paint)
(repaint void))
(super-new [parent f]))))
(define platform-p (and (string? (wx:color-from-user-platform-mode))
(new horizontal-panel%
[parent f]
[alignment '(right center)])))
(define p (make-object vertical-pane% f))
(define (repaint ext)
(let ([c (get-current-color)])
(ext c)
(wx:fill-private-color (send canvas get-dc) c)))
(define (update-and-repaint s e)
(repaint
(lambda (c)
(when platform-p
(wx:get-color-from-user c)))))
(define (make-color-slider l) (make-object slider% l 0 255 p update-and-repaint))
(define red (make-color-slider "Red:"))
(define green (make-color-slider "Green:"))
(define blue (make-color-slider "Blue:"))
(define alpha (and (member 'alpha style)
(new text-field%
[parent p]
[label "Alpha:"]
[callback
(λ (_1 _2)
(update-ok-button-and-background))])))
(define (update-ok-button-and-background)
(when alpha
(define n (string->number (send alpha get-value)))
(define ok? (and n (real? n) (<= 0 n 1)))
(send ok-button enable ok?)
(send alpha set-field-background
(send wx:the-color-database find-color
(if ok? "white" "pink")))))
(define bp (make-object horizontal-pane% f))
(define (get-current-color)
(make-object wx:color%
(send red get-value)
(send green get-value)
(send blue get-value)
(if alpha
(string->number (send alpha get-value))
1.0)))
(define (install-color color)
(send red set-value (send color red))
(send green set-value (send color green))
(send blue set-value (send color blue))
(when alpha (send alpha set-value (format "~a" (send color alpha))))
(send canvas refresh))
(when platform-p
(new button%
[parent platform-p]
[label (wx:color-from-user-platform-mode)]
[callback (lambda (b e) (wx:get-color-from-user 'show))])
(wx:get-color-from-user (or color
(make-object wx:color% 0 0 0)))
(send (mred->wx f) set-color-callback (lambda ()
(install-color
(wx:get-color-from-user 'get)))))
(when color (install-color color))
(define-values (ok-button cancel-button)
(ok-cancel
(lambda ()
(make-object button% "OK" bp (done #t) '(border)))
(lambda ()
(make-object button% "Cancel" bp (done #f)))))
(send ok-button focus)
(update-ok-button-and-background)
(send bp set-alignment 'right 'center)
(send p set-alignment 'right 'center)
(send p stretchable-height #f)
(send canvas min-height 50)
(send f center)
(send f show #t)
(and ok?
(get-current-color))])]))