#lang scheme
(require "code-write.ss"
"mreddesigner-misc.ss")
(define/provide (flat-prop->prop val)
(cond [(is-a? val property<%>) val]
[(atom? val)
(make-object prop:atom% val)]
[(list? val)
(make-object prop:atom% val)] [else
(printf "flat-prop->prop: Don't know what to do with ~a\n" val)]
)
)
(define/provide (prop->val p)
(cond [(is-a? p property<%>)
(send p get-value)]
[(symbol? p) (list 'quote p)]
[(list? p) (cons 'list (map prop->val p))]
[(path? p) (path->string p)] [else p]
))
(define/provide property<%>
(interface () get-value generate-code))
(define (prop-value%% c%)
(class* (code-write%% c%) (property<%>)
(super-new)
(init-field value)
(code-fields value)
(field [update-callback #f])
(define/public (get-value)
value
)
(define/public (set-value v)
(set! value v)
(update) )
(define/public (generate-pre-code)
'()
)
(define/public (generate-code)
value
)
(define/public (set-update-callback proc)
(set! update-callback proc)
)
(define/public (update)
(when update-callback (update-callback this)))
))
(define prop:value%
(class (prop-value%% object%)
(super-new)
(inherit-field value)
(define/override (generate-code)
(prop->val value))
))
(define/provide prop:field-id%
(class prop:value%
(init-field field-id [option #f] [necessary #f] [no-code #f] [hidden #f])
(code-fields field-id option necessary no-code hidden)
(super-new)
(getter field-id necessary no-code hidden)
(getter/setter option)
(inherit-field value)
(define/public (get-prop) value)
(define/override (get-value)
(send value get-value))
(define/override (update)
(send value update))
(define/override (generate-pre-code)
(send value generate-pre-code))
(define/public (option-symbol [prefix ""])
(symbol-append* prefix field-id))
(define/public (option-keyword [prefix ""])
(symbol->keyword (option-symbol prefix)))
(define/public (generate-option [prefix ""])
(if option
(list (option-keyword prefix)
(list (option-symbol prefix) (send value generate-code)))
'()))
(define/override (generate-code [prefix ""])
(if option
(option-symbol prefix)
(send value generate-code)))
))
(define/provide prop:atom%
(class prop:value% (super-new)))
(define/provide (prop:atom v)
(new prop:atom% [value v]))
(define/provide prop:boolean%
(class prop:value%
(init-field label)
(code-fields label)
(getter label)
(super-new)))
(define/provide (prop:bool label v)
(new prop:boolean% [label label] [value v]))
(define/provide prop:file%
(class prop:value% (super-new)
(inherit-field value)
(define/override (generate-code)
(if (and value (use-runtime-paths?))
(symbol-append* (send (current-property-mred-id) get-id)
"-runtime-path")
(prop->val value)))
(define/override (generate-pre-code)
(if (and value (use-runtime-paths?))
(list
(list 'define-runtime-path (symbol-append* (send (current-property-mred-id) get-id)
"-runtime-path")
(prop->val value)))
'()))
))
(define/provide (prop:file v)
(new prop:file% [value v]))
(define/provide prop:one-of%
(class prop:value%
[init-field choices]
(field [prop-choices choices])
(super-new)
(code-fields choices)
(getter prop-choices)
))
(define/provide (prop:one-of choices val)
(make-object prop:one-of% choices val))
(define prop:value-list%
(class prop:value%
(super-new)
(inherit-field value)
(define/override (get-value)
(map-send get-value value))
(define/override (generate-pre-code)
(apply append
(map-send generate-pre-code value)))
(define/override (generate-code)
(cons 'list (map-send generate-code value)))
))
(define/provide prop:some-of%
(class prop:value%
(init-field choices)
(super-new)
(inherit-field value)
(code-fields choices)
(getter choices)
(define/override (generate-code)
(list 'quote value))
))
(define/provide (prop:some-of choices val-list)
(make-object prop:some-of% choices val-list))
(define/provide prop:group%
(class prop:value%
(super-new)
(inherit-field value)
(define/public (get-props) value)
(define/override (get-value)
(map-send get-value value))
(define/override (generate-pre-code)
(apply append (map-send generate-pre-code value)))
(define/override (generate-code)
(cons 'list (map-send generate-code value)))
(define/override (update) (for-each-send update value))
))
(define/provide (prop:group . vlist)
(make-object prop:group% (map flat-prop->prop vlist)))
(define/provide prop:hgroup% (class prop:group% (super-new)))
(define/provide (prop:hgroup . vlist)
(make-object prop:hgroup% (map flat-prop->prop vlist)))
(define/provide prop:popup%
(class prop:value%
(super-new)
(inherit-field value)
(define/public (get-prop) value)
(define/override (get-value)
(send value get-value))
(define/override (generate-pre-code)
(send value generate-pre-code))
(define/override (generate-code)
(send value generate-code))
(define/override (update)
(send value update))
))
(define/provide (prop:popup val)
(make-object prop:popup% (flat-prop->prop val)))
(define/provide prop:code%
(class prop:value%
(super-new)
(init-field value-code)
(define/override (code-write-args)
(list (list 'value value-code)
(list 'value-code (list 'quote value-code))))
(setter value-code)
(define/override (generate-code)
value-code)
))
(provide prop:code)
(define-syntax-rule (prop:code fun)
(new prop:code% [value fun]
[value-code 'fun]))
(provide prop:code-set-value)
(define-syntax-rule (prop:code-set-value prop fun)
(begin
(send prop set-value-code 'fun)
(send prop set-value fun)))
(define/provide prop:proc%
(class prop:value%
(inherit-field value)
(super-new)
(init-field prop-code
[generate-quoted-code #t])
(code-fields prop-code generate-quoted-code)
(setter prop-code)
(define/public (get-prop) value)
(define/override (get-value)
((send prop-code get-value) (send value get-value)))
(define/override (generate-pre-code)
(append
(send prop-code generate-pre-code)
(send value generate-pre-code)))
(define/override (generate-code)
(if generate-quoted-code
(list (send prop-code generate-code)
(send value generate-code))
(get-value)
))
))
(provide prop:proc)
(define-syntax-rule (prop:proc v fun)
(new prop:proc% [value (flat-prop->prop v)]
[prop-code (prop:code fun)]))
(provide prop:proc-unquoted)
(define-syntax-rule (prop:proc-unquoted v fun)
(new prop:proc% [value (flat-prop->prop v)]
[prop-code (prop:code fun)]
[generate-quoted-code #f]
))