(defmacro define-burden (name inputs outputs &key (button "Calculate")) (let ((input-labels (loop for (input) in inputs collect (gensym (format nil "IN-LABEL/~a" input)))) (output-labels (loop for (output) in outputs collect (gensym (format nil "OUT-LABEL/~a" output)))) (update-name (gensym "UPDATE-BURDEN")) (slots (append (mapcar #'first inputs) (mapcar #'first outputs)))) `(progn (clim:define-application-frame ,name () ,slots (:panes ,@(append (loop for (input-name . arguments) in inputs for label-name in input-labels for label = (getf arguments :label (string-capitalize input-name)) appending `((,label-name (clim:make-pane 'clim:label-pane :label ,label)) (,input-name (clim:make-pane 'clim:text-field)))) `((button (clim:make-pane 'clim:push-button :label ,button :activate-callback #',update-name))) (loop for (output-name value . arguments) in outputs for label-name in output-labels for label = (getf arguments :label (string-capitalize output-name)) appending `((,output-name (clim:make-pane 'clim:text-field)) (,label-name (clim:make-pane 'clim:label-pane :label ,label)))))) (:layouts (default (progn ,@(loop for slot in slots collect `(setf (slot-value clim:*application-frame* ',slot) ,slot)) (clim:vertically (:width 500) (clim:tabling () ,@(loop for (input-name) in inputs for label-name in input-labels collect `(list ,label-name ,input-name))) button (clim:tabling () ,@(loop for (output-name) in outputs for label-name in output-labels collect `(list ,label-name ,output-name)))))))) (defun ,update-name (gadget) (declare (ignore gadget)) (let ((*read-eval* nil)) (let ,(loop for (input-name) in inputs collect `(,input-name (read-from-string (clim:gadget-value (slot-value clim:*application-frame* ',input-name))))) (let* ,(loop for (output-name value) in outputs collect `(,output-name ,value)) ,@(loop for (output-name value . options) in outputs for formatter = (getf options :format "~$") collect `(setf (clim:gadget-value (slot-value clim:*application-frame* ',output-name)) (format nil ,formatter ,output-name))))))))))