#lang scheme
(require "mreddesigner-misc.ss"
"preview-widgets.ss"
"toolbox-frame.ss"
"property-frame.ss"
"hierarchy-frame.ss"
"code-generation.ss"
"templates.ss"
framework
"mred-plugin.ss"
scheme/gui/base
"mred-id.ss"
)
(define/provide (controller-exit-application)
(let ([projects (map-send user-data (send hierarchy-widget get-items))])
(for-each project-changed-save projects))
(close-window hierarchy-frame)
(close-window property-frame)
(close-window toolbox-frame)
)
(define/provide (controller-show-property-frame)
(send property-frame show
(not (send property-frame is-shown?))))
(define/provide (controller-show-hierarchy-frame)
(send hierarchy-frame show
(not (send hierarchy-frame is-shown?))))
(define/provide (controller-select-mred-id mid)
(select-mred-id mid)
(hierarchy-select mid)
(update-property-frame mid)
(update-toolbox-frame mid)
)
(define/provide (controller-replace-current-widget)
(send (get-current-mred-id) replace-widget)
(send hierarchy-widget update-current-mred-id)
)
(define/provide (controller-create-mred-id plugin [mred-parent (get-current-mred-id)])
(let* ([new-mred-id (send plugin new-mred-id mred-parent)])
(when new-mred-id
(project-changed! new-mred-id)
(if mred-parent
(send hierarchy-widget add-child new-mred-id)
(send hierarchy-widget add-child new-mred-id #f))
)))
(define/provide (controller-delete-mred-id [mid (get-current-mred-id)])
(when mid
(let ([mid-parent (send mid get-mred-parent)])
(unless mid-parent
(project-changed-save mid)
)
(send mid delete)
(project-changed! mid)
(send hierarchy-widget delete-mred-id mid)
(controller-select-mred-id mid-parent)
)))
(define/provide (controller-move-up)
(let* ([mid (get-current-mred-id)])
(send mid move-up)
(project-changed!)
(send hierarchy-widget move-up)
))
(define/provide (controller-move-down)
(let* ([mid (get-current-mred-id)])
(send mid move-down)
(project-changed!)
(send hierarchy-widget move-down)
))
(define (load-mred file parent-mid)
(when file
(begin-busy-cursor)
(debug-printf "loading file ~a\n" file)
(let* ([tlmid (and parent-mid (send parent-mid get-top-mred-parent))]
[all-ids (if tlmid (map-send get-id (get-all-children tlmid)) '())]
[all-ids-str (map ->string all-ids)]
[mids (load-template file parent-mid)])
(end-busy-cursor)
(and mids
(begin
(when parent-mid
(for-each (λ(m)
(let* ([id (send m get-id)]
[id-str (->string id)]
[id-exists? (member id-str all-ids-str)])
(when id-exists?
(send m set-random-id))))
mids)
)
(send hierarchy-widget add-child (first mids)
(if parent-mid (send hierarchy-widget get-selected) #f))
mids
)))
))
(define/provide (controller-load-template file [parent-mid (get-current-mred-id)])
(when file
(unless (load-mred file parent-mid)
(printf "Error: cannot load template file ~a\n" file))))
(define/provide (controller-save-template name [file #f] [mid (get-current-mred-id)])
(when mid
(save-template mid name file)
(controller-update-templates)
))
(define/provide (controller-replace-current-template file)
(save-template (get-current-mred-id) (get-template-name file) file)
)
(define/provide (controller-delete-template file)
(delete-template file)
(controller-update-templates)
)
(define/provide (controller-update-templates)
(make-template-dict)
(toolbox-update-template-choices)
)
(define/provide (controller-copy)
(controller-save-template "Clipboard" (template-file "clipboard"))
)
(define/provide (controller-cut)
(controller-copy)
(controller-delete-mred-id)
(project-changed!)
)
(define/provide (controller-paste)
(controller-load-template (template-file "clipboard"))
(project-changed!)
)
(define (set-project-changed project-mid val)
(send
(send (send project-mid get-property 'changed) get-prop)
set-value val))
(define/provide (project-changed! [some-mid-child (get-current-mred-id)])
(set-project-changed (send some-mid-child get-top-mred-parent) #t))
(define/provide (controller-close-project [some-mild-child (get-current-mred-id)])
(when some-mild-child
(let ([mid (send some-mild-child get-top-mred-parent)])
(controller-delete-mred-id mid))))
(define/provide (project-changed-save project-mid)
(when (send project-mid get-property-value 'changed)
(let ([save? (message-box
"Save project?"
(string-append*
"Do you want to save the project "
(send project-mid get-id)
" before closing it?")
#f
'(yes-no caution))])
(when (equal? save? 'yes)
(controller-save-project #f project-mid)))))
(define/provide (controller-new-project)
(controller-create-mred-id (get-widget-plugin 'project) #f))
(define/provide (load-project file)
(let ([mids (load-mred file #f)])
(or
(and mids
(let ([proj-mid (first mids)])
(send (send (send proj-mid get-property 'file) get-prop)
set-value (path->string file))
(set-project-changed proj-mid #f)
proj-mid))
(and (printf "Error: cannot load project ~a\n" file)
#f))))
(define/provide (controller-load-project)
(let ([file (get-file "Select a MrEd Designer Project File"
#f #f #f "med" '()
'(("MrEd Designer Project File" "*.med"))
)])
(and file
(let ([proj-mid (load-project file)])
proj-mid))
))
(define/provide (save-project mid file)
(when mid
(let ([project-mid (send mid get-top-mred-parent)])
(send (send (send project-mid get-property 'file) get-prop)
set-value (path-string->string file))
(save-template project-mid (->string (send project-mid get-id)) file)
(set-project-changed project-mid #f)
)))
(define/provide (controller-save-project [save-as? #f] [mid (get-current-mred-id)])
(when mid
(let* ([project-mid (send mid get-top-mred-parent)]
[file (or (and (not save-as?)
(send project-mid get-property-value 'file))
(put-file "Select a file to save your MrEd Designer Project"
toolbox-frame
#f
(symbol->string (send project-mid get-id))
"*.med"
'()
'(("MrEd Designer Project (.med)" "*.med"))
))]
[filestr (and file (->string file))]
[filestr (if (and filestr (not (regexp-match "\\.med$" filestr)))
(string-append filestr ".med")
filestr)])
(when filestr
(save-project project-mid filestr))
)))
(define (choose-code-file dft-name [base-path #f] [parent-frame #f])
(let ([base-path (and base-path (normal-case-path (simple-form-path base-path)))]
[file (put-file "Select the file to generate the code to"
parent-frame
base-path
dft-name
"*.ss"
'()
'(("Scheme (.ss)" "*.ss")
("Scheme (.scm)" "*.scm")
("Any" "*.*")))])
(if file
(if base-path
(let ([file (normal-case-path (simple-form-path file))]
[relative (message-box "Relative or global path?"
"Save file as relative to project path?"
parent-frame
'(yes-no))])
(path->string
(if (symbol=? 'yes relative)
(find-relative-path base-path file)
file)))
(path->string file))
#f)))
(define/provide (controller-generate-code-to-console [mid (get-current-mred-id)])
(when mid
(let ([project-mid (send mid get-top-mred-parent)])
(generate-module project-mid))))
(define/provide (controller-generate-code [mid (get-current-mred-id)])
(when mid
(let* ([project-mid (send mid get-top-mred-parent)]
[proj-file (send project-mid get-property-value 'file)]
[base-dir (and proj-file (path-only (string->path proj-file)))]
[file (or (send project-mid get-property-value 'code-file)
(choose-code-file
(symbol->string (send project-mid get-id))
base-dir
toolbox-frame))]
)
(when file
(parameterize ([current-directory (or base-dir (current-directory))])
(with-output-to-file file
(λ()(generate-module project-mid))
#:exists 'replace)
)))))