racket/collects/framework/private/gen-standard-menus.rkt

288 lines
13 KiB
Racket

#reader scribble/reader
#lang scheme
(provide main)
(require scheme/pretty
scheme/runtime-path)
(require "standard-menus-items.ss")
(define-runtime-path here ".")
(define standard-menus.rkt-filename (simplify-path (build-path here "standard-menus.rkt")))
(define docs-menus.ss-filename (simplify-path (build-path here 'up 'up "scribblings" "framework" "standard-menus.scrbl")))
;; build-before-super-item-clause : an-item -> (listof clause)
(define build-before-super-item-clause
(λ (item)
(list
`[define/public ,(an-item->callback-name item) ,(an-item-proc item)]
`(define/public (,(an-item->get-item-name item))
,(an-item->item-name item))
`(define/public (,(an-item->string-name item))
,(an-item-menu-string item))
`(define/public (,(an-item->help-string-name item))
,(an-item-help-string item))
`(define/public ,(an-item->on-demand-name item) ,(an-item-on-demand item))
`(define/public (,(an-item->create-menu-item-name item))
,(an-item-create item)))))
;; build-before-super-clause : ((X -> sym) (X sexp) -> X -> (listof clause))
(define build-before-super-clause
(λ (->name -procedure)
(λ (obj)
(list `(define/public ,(->name obj)
,(case (-procedure obj)
[(nothing) '(λ (menu) (void))]
[(separator) '(λ (menu) (make-object separator-menu-item% menu))]
[(nothing-with-standard-menus)
'(λ (menu)
(unless (current-eventspace-has-standard-menus?)
(make-object separator-menu-item% menu)))]
[else (error 'gen-standard-menus "unknown between sym: ~e" (-procedure obj))]))))))
;; build-before-super-between-clause : between -> (listof clause)
(define build-before-super-between-clause
(build-before-super-clause
between->name
between-procedure))
;; build-before-super-before/after-clause : before/after -> (listof clause)
(define build-before-super-before/after-clause
(build-before-super-clause
before/after->name
before/after-procedure))
;; build-after-super-item-clause : an-item -> (list clause)
(define (build-after-super-item-clause item)
(let* ([callback-name (an-item->callback-name item)]
[create-menu-item-name (an-item->create-menu-item-name item)]
[callback-name-string (symbol->string callback-name)]
[key (an-item-shortcut item)])
(list `(define
,(an-item->item-name item)
(and (,create-menu-item-name)
,(if (a-submenu-item? item)
`(new (get-menu%)
(label (,(an-item->string-name item)))
(parent ,(menu-item-menu-name item))
(help-string (,(an-item->help-string-name item)))
(demand-callback (λ (menu-item) (,(an-item->on-demand-name item) menu-item))))
`(new ,(if (a-checkable-item? item)
'(get-checkable-menu-item%)
'(get-menu-item%))
(label (,(an-item->string-name item)))
(parent ,(menu-item-menu-name item))
(callback (let ([,callback-name (λ (item evt) (,callback-name item evt))])
,callback-name))
(shortcut ,key)
(shortcut-prefix ,(an-item-shortcut-prefix item))
(help-string (,(an-item->help-string-name item)))
(demand-callback (λ (menu-item) (,(an-item->on-demand-name item) menu-item))))))))))
;; build-after-super-clause : ((X -> symbol) -> X -> (listof clause))
(define build-after-super-clause
(λ (->name)
(λ (between/after)
(list
`(,(->name between/after)
(,(menu-name->get-menu-name between/after)))))))
;; build-after-super-between-clause : between -> (listof clause)
(define build-after-super-between-clause (build-after-super-clause between->name))
;; build-after-super-before/after-clause : before/after -> (listof clause)
(define build-after-super-before/after-clause (build-after-super-clause before/after->name))
;; build-after-super-generic-clause : generic -> (listof clause)
(define (build-after-super-generic-clause x)
(cond
[(generic-private-field? x)
(list `(define
,(generic-name x)
,(generic-initializer x)))]
[(generic-override? x)
(list)]
[(generic-augment? x)
(list)]
[(generic-method? x)
null]))
;; build-before-super-generic-clause : generic -> (listof clause)
(define (build-before-super-generic-clause generic)
(cond
[(generic-private-field? generic)
null]
[(generic-override? generic)
(list `(define/override ,(generic-name generic)
,(generic-initializer generic)))]
[(generic-augment? generic)
(list `(define/augment ,(generic-name generic)
,(generic-initializer generic)))]
[(generic-method? generic)
(list `(define/public ,(generic-name generic)
,(generic-initializer generic)))]))
(define (main)
(write-standard-menus.rkt)
(write-docs))
(define (write-docs)
(printf "writing to ~a\n" docs-menus.ss-filename)
(call-with-output-file docs-menus.ss-filename
(λ (port)
(define (pop-out sexp)
(display "@" port)
(write sexp port)
(newline port)
(newline port))
(display docs-header-text port)
(for-each (λ (x)
(cond
[(generic/docs? x)
(for-each
(λ (x) (unless (string? x) (pop-out x)))
(generic/docs-documentation x))]
[(before/after? x)
(pop-out
`@defmethod[(,(before/after->name x) [menu (is-a?/c menu-item%)]) void?]{
This method is called @,(if (before? x) "before" "after") the addition of the
@tt[,(format "~a" (before/after-name x))] menu-item. Override it to add additional
menu items at that point. })]
[(between? x)
(pop-out
`@defmethod[(,(between->name x) [menu (is-a?/c menu-item%)]) void?]{
This method is called between the addition of the
@tt[,(format "~a" (between-before x))] and the @tt[,(format "~a" (between-after x))] menu-item.
Override it to add additional menu items at that point. })]
[(an-item? x)
(pop-out
`@defmethod[(,(an-item->get-item-name x)) (or/c false/c (is-a?/c menu-item%))]{
This method returns the @scheme[menu-item%] object corresponding
to this menu item, if it has been created (as controlled by
@method[frame:standard-menus<%> ,(an-item->create-menu-item-name x)]).})
(pop-out
`@defmethod[(,(an-item->create-menu-item-name x)) boolean?]{
The result of this method determines if the corresponding
menu item is created. Override it to control the creation of the menu item.
Defaults to @scheme[,(an-item-create x)].})
(match (an-item-proc x)
[`(λ (,item-name ,evt-name) ,bodies ...)
(pop-out
`@defmethod[(,(an-item->callback-name x)
[,item-name (is-a?/c menu-item%)]
[,evt-name (is-a?/c control-event%)])
void?]{
Defaults to @schemeblock[,(if (= 1 (length bodies))
(car bodies)
`(begin ,@bodies))] })])
(match (an-item-on-demand x)
[`(λ (,item-name) ,body)
(pop-out
`@defmethod[(,(an-item->on-demand-name x) [,item-name (is-a?/c menu-item%)]) void?]{
The menu item's on-demand proc calls this method.
Defaults to @schemeblock[,body]})])
(pop-out
`@defmethod[(,(an-item->string-name x)) string?]{
The result of this method is used as the name of the @scheme[menu-item%].
Defaults to @scheme[,(an-item-menu-string x)].})
(pop-out
`@defmethod[(,(an-item->help-string-name x)) string?]{
The result of this method is used as the help string
when the @scheme[menu-item%] object is created.
Defaults to @scheme[,(an-item-help-string x)].})]))
items)
(display docs-footer-text port))
#:exists 'truncate))
(define (write-standard-menus.rkt)
(printf "writing to ~a\n" standard-menus.rkt-filename)
(call-with-output-file standard-menus.rkt-filename
(λ (port)
(pretty-print
`(define standard-menus<%>
(interface (basic<%>)
,@(apply append (map
(λ (x)
(cond
[(an-item? x)
(list
(an-item->callback-name x)
(an-item->get-item-name x)
(an-item->string-name x)
(an-item->help-string-name x)
(an-item->on-demand-name x)
(an-item->create-menu-item-name x))]
[(between? x) (list (between->name x))]
[(or (after? x) (before? x))
(list (before/after->name x))]
[(generic? x)
(if (generic-method? x)
(list (generic-name x))
null)]))
items))))
port)
(newline port)
(pretty-print
`(define standard-menus-mixin
(mixin (basic<%>) (standard-menus<%>)
(inherit on-menu-char on-traverse-char)
(define remove-prefs-callback
(preferences:add-callback
'framework:menu-bindings
(λ (p v)
(let loop ([menu (get-menu-bar)])
(when (is-a? menu menu:can-restore<%>)
(if v
(send menu restore-keybinding)
(send menu set-shortcut #f)))
(when (is-a? menu menu:can-restore-underscore<%>)
(if v
(send menu restore-underscores)
(send menu erase-underscores)))
(when (is-a? menu menu-item-container<%>)
(for-each loop (send menu get-items)))))))
(inherit get-menu-bar show can-close? get-edit-target-object)
,@(apply append (map (λ (x)
(cond
[(between? x) (build-before-super-between-clause x)]
[(or (after? x) (before? x)) (build-before-super-before/after-clause x)]
[(an-item? x) (build-before-super-item-clause x)]
[(generic? x) (build-before-super-generic-clause x)]))
items))
(super-instantiate ())
,@(apply append (map (λ (x)
(cond
[(between? x) (build-after-super-between-clause x)]
[(an-item? x) (build-after-super-item-clause x)]
[(or (after? x) (before? x)) (build-after-super-before/after-clause x)]
[(generic? x) (build-after-super-generic-clause x)]))
items))
(reorder-menus this)))
port))
#:mode 'text
#:exists 'truncate))
(define docs-footer-text "}")
(define docs-header-text #<<--
;; THIS FILE IS GENERATED. DO NOT EDIT.
@definterface[frame:standard-menus<%> (frame:basic<%>)]{
--
)