3 ;;; Dependency-based user interfaces
5 ;;; (c) 2007 Mark Wooding
8 ;;;----- Licensing notice ---------------------------------------------------
10 ;;; This program is free software; you can redistribute it and/or modify
11 ;;; it under the terms of the GNU General Public License as published by
12 ;;; the Free Software Foundation; either version 2 of the License, or
13 ;;; (at your option) any later version.
15 ;;; This program is distributed in the hope that it will be useful,
16 ;;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;;; GNU General Public License for more details.
20 ;;; You should have received a copy of the GNU General Public License
21 ;;; along with this program; if not, write to the Free Software Foundation,
22 ;;; Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 ;;;--------------------------------------------------------------------------
27 ;;; Generic interface.
31 (defun update-text-field-dep (field dep convert-func)
32 (let ((text (field-text field)))
33 (multiple-value-bind (value bogusp) (funcall convert-func text)
35 (set-field-highlight field :bad)
38 (unless (dep-goodp dep)
39 (set-field-highlight field :good))
40 (setf (dep-value dep) value))))))
42 (defun make-text-field-with-dep (convert-func dep)
44 :notify (lambda (field)
45 (update-text-field-dep field dep convert-func))))
47 (defun update-dep-text-field (field dep convert-func)
48 (multiple-value-bind (highlight value)
50 (values :good (dep-value dep))
52 (set-field-highlight field highlight)
53 (setf (field-text field) (funcall convert-func value))))
55 (defun make-dependent-text-field
56 (dep &optional (convert-func #'princ-to-string))
57 (let ((field (make-text-field :readonly t)))
58 (flet ((kicked (&optional ev)
60 (update-dep-text-field field dep convert-func)))
61 (dep-add-listener dep #'kicked)
65 (defun safe-read-from-string (string continuation)
66 (with-input-from-string (stream string)
68 (let ((value (let ((*read-eval* nil)) (read stream))))
69 (if (peek-char t stream nil)
71 (funcall continuation value))))))
73 (defun read-real-from-string (string)
74 (safe-read-from-string string
76 (values value (not (realp value))))))
78 (defun make-input (label dep &key (convert #'read-real-from-string))
79 (let ((text (make-text-field-with-dep convert dep)))
80 (pack-labelled-widget *panel* label text)))
82 (defun make-output (label dep &key (convert "~,3F"))
83 (let ((text (make-dependent-text-field dep
87 (format nil convert value)))
90 (pack-labelled-widget *panel* label text)))
92 (defun make-radio-dep (dep plist)
93 (let ((group (make-radio-group
94 (lambda (value) (setf (dep-value dep) value))
96 :default (if (dep-goodp dep)
98 (setf (dep-value dep) (cadr plist))))))
99 (pack-single-widget *panel* group)))
102 (defmacro within-group ((label) &body body)
103 `(let ((*panel* (pack-single-widget *panel* (make-group ,label))))
109 (defun drop-reason ()
110 (assert (plusp reasons))
112 (when (zerop reasons)
115 (defmacro defwindow (name bvl (title) &body body)
117 (make-toplevel ,title (lambda () ,@body))))
119 ;;;----- That's all, folks --------------------------------------------------