lux/chaos/gui.rkt

141 lines
3.7 KiB
Racket
Raw Normal View History

2014-11-19 22:48:05 +00:00
#lang racket/base
(require racket/match
racket/class
racket/contract/base
racket/gui/base
2014-11-20 15:53:15 +00:00
racket/async-channel
2014-11-19 22:48:05 +00:00
lux/chaos)
2015-04-10 23:04:21 +00:00
;; Robby says that I could rework this to remove the event-ch by
;; having capturing the continuation, storing it, and then calling it
;; from within the callback once an event is ready.
2014-11-26 22:21:55 +00:00
(struct gui (event-ch drawer frame refresh!)
2014-11-19 22:48:05 +00:00
#:methods gen:chaos
2014-11-21 18:26:01 +00:00
[(define (chaos-yield c e)
2014-11-21 21:07:23 +00:00
(yield e))
2014-11-20 15:53:15 +00:00
(define (chaos-event c)
(gui-event-ch c))
2014-11-19 22:48:05 +00:00
(define (chaos-output! c o)
2014-11-22 18:54:08 +00:00
(when o
(set-box! (gui-drawer c) o))
2014-11-19 22:48:05 +00:00
((gui-refresh! c)))
(define (chaos-label! c l)
2014-11-20 03:55:32 +00:00
(send (gui-frame c) set-label l))
2014-11-26 22:21:55 +00:00
(define (chaos-stop! c)
(send (gui-frame c) show #f))])
2014-11-19 22:48:05 +00:00
2014-11-21 18:26:01 +00:00
(define (make-gui #:mode [mode 'draw]
2014-11-26 22:21:55 +00:00
#:start-fullscreen? [start-fullscreen? #f]
2014-11-21 21:07:23 +00:00
#:icon [icon #f]
2015-04-28 00:45:28 +00:00
#:width [the-init-w #f]
#:height [the-init-h #f])
(define-values (start-x start-y init-w init-h)
(cond
[start-fullscreen?
(define-values (x y) (get-display-left-top-inset #t))
(define-values (w h) (get-display-size #t))
(values (* -1 x) (* -1 y) w h)]
[else
2015-04-28 22:50:39 +00:00
(values #f #f 800 600)]))
2015-04-28 00:45:28 +00:00
;; xxx start-x/y isn't working
2014-11-20 15:53:15 +00:00
(define events-ch (make-async-channel))
2014-11-19 22:48:05 +00:00
(define gframe%
(class frame%
(define/override (on-size w h)
2015-05-01 00:29:41 +00:00
(async-channel-put events-ch (list 'resize w h))
2014-11-19 22:48:05 +00:00
(refresh!))
(define/augment (on-close)
2014-11-20 15:53:15 +00:00
(async-channel-put events-ch 'close))
2014-11-19 22:48:05 +00:00
(define/override (on-subwindow-char w ke)
2014-11-20 15:53:15 +00:00
(async-channel-put events-ch ke))
2014-11-19 22:48:05 +00:00
(define/override (on-subwindow-event w me)
2014-11-20 15:53:15 +00:00
(async-channel-put events-ch me))
2014-11-19 22:48:05 +00:00
(super-new)))
(define drawer (box void))
(define (paint-canvas c dc)
((unbox drawer)
(send c get-width)
(send c get-height)
dc))
2015-05-01 00:29:41 +00:00
;; (printf "starting at ~v\n" (vector start-x start-y))
2015-04-28 00:45:28 +00:00
2014-11-19 22:48:05 +00:00
(define f
(new gframe%
[label ""]
2015-04-28 00:45:28 +00:00
[x start-x]
[y start-y]
2014-11-19 22:48:05 +00:00
[width init-w]
[height init-h]
2015-04-28 00:45:28 +00:00
[style
(if start-fullscreen?
'(hide-menu-bar no-resize-border)
'())]))
2014-11-19 22:48:05 +00:00
(define gl-config
(match mode
['draw #f]
2014-11-22 18:54:08 +00:00
['gl-compat
2014-11-19 22:48:05 +00:00
(new gl-config%)]
2014-11-22 18:54:08 +00:00
['gl-core
2014-11-19 22:48:05 +00:00
(define gl-config (new gl-config%))
2014-11-26 22:21:55 +00:00
(send gl-config set-legacy? #f)
gl-config]
2014-11-19 22:48:05 +00:00
[gl-config
gl-config]))
(define c
(new canvas% [parent f]
[paint-callback paint-canvas]
2014-11-26 22:21:55 +00:00
[gl-config gl-config]
2014-11-19 22:48:05 +00:00
[style
(cons 'no-autoclear
(if gl-config '(gl) '()))]))
2015-04-10 23:04:21 +00:00
(define the-refresh-sema (make-semaphore 0))
2014-11-19 22:48:05 +00:00
(define (refresh!)
2015-04-10 23:04:21 +00:00
(queue-callback
2015-04-28 00:45:28 +00:00
(λ ()
2015-04-10 23:04:21 +00:00
(send c refresh-now)
(semaphore-post the-refresh-sema))
#f)
(yield the-refresh-sema))
2014-11-19 22:48:05 +00:00
2015-04-28 00:45:28 +00:00
(cond
[start-fullscreen?
(send f move start-x start-y)]
[else
(send f center)])
2014-11-19 22:48:05 +00:00
(send f show #t)
2014-11-21 21:07:23 +00:00
(when icon
(define icon-bm
(if (is-a? icon bitmap%)
icon
(read-bitmap icon)))
(when (eq? 'macosx (system-type 'os))
2014-11-23 18:57:04 +00:00
((dynamic-require 'drracket/private/dock-icon 'set-dock-tile-bitmap)
icon-bm)))
2014-11-21 21:07:23 +00:00
2014-11-26 22:21:55 +00:00
(gui events-ch drawer f refresh!))
2014-11-19 22:48:05 +00:00
(provide
(contract-out
[make-gui
2014-11-21 18:26:01 +00:00
(->* ()
2014-11-19 22:48:05 +00:00
(#:mode
2014-11-22 18:54:08 +00:00
(or/c (one-of/c 'draw 'gl-compat 'gl-core)
2014-11-19 22:48:05 +00:00
(is-a?/c gl-config%))
2014-11-26 22:21:55 +00:00
#:start-fullscreen?
boolean?
2014-11-21 21:07:23 +00:00
#:icon
2014-11-22 18:54:08 +00:00
(or/c #f path-string? (is-a?/c bitmap%))
2014-11-19 22:48:05 +00:00
#:width
exact-nonnegative-integer?
#:height
exact-nonnegative-integer?)
chaos?)]))