File: mchoices.lisp

package info (click to toggle)
clue 20011230
  • links: PTS
  • area: main
  • in suites: woody
  • size: 6,112 kB
  • ctags: 2,646
  • sloc: lisp: 31,991; makefile: 40; sh: 24
file content (221 lines) | stat: -rw-r--r-- 8,923 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
;; -*- Mode:Lisp; Package:CLIO-OPEN; Base:10; Lowercase:T; Fonts:(CPTFONT); Syntax:Common-Lisp -*-


;;;----------------------------------------------------------------------------------+
;;;                                                                                  |
;;;                          TEXAS INSTRUMENTS INCORPORATED                          |
;;;                                  P.O. BOX 149149                                 |
;;;                                AUSTIN, TEXAS 78714                               |
;;;                                                                                  |
;;;             Copyright (C) 1989, 1990 Texas Instruments Incorporated.             |
;;;                                                                                  |
;;; Permission is granted to any individual or institution to use, copy, modify, and |
;;; distribute this software, provided that  this complete copyright and  permission |
;;; notice is maintained, intact, in all copies and supporting documentation.        |
;;;                                                                                  |
;;; Texas Instruments Incorporated provides this software "as is" without express or |
;;; implied warranty.                                                                |
;;;                                                                                  |
;;;----------------------------------------------------------------------------------+

(in-package "CLIO-OPEN")

(EXPORT '(
	  choice-default
	  choice-font
	  choice-selection
	  make-multiple-choices
	  multiple-choices
	  ))


;;;  ============================================================================
;;;	     T h e   M U L T I P L E   -   C H O I C E S   C o n t a c t
;;;  ============================================================================

(DEFCONTACT multiple-choices (table)
  
  ((font 	:type 		fontable
	 	:reader 	choice-font
		:initarg	:font
	 	:initform 	nil)
    
   (selection   :type           list
                :accessor       choice-selection
                :initform       nil)

   (default	:type		list
                :accessor       choice-default
		:initarg	:default-selection
		:initform	nil)
   )
  
  (:resources
    font default
    (horizontal-space :initform 3)
    (vertical-space :initform 3))

  (:documentation
    "Provides a mechanism for displaying N choices to a user of which the user may select M,
where N >= M >= 0."))



(DEFUN make-multiple-choices (&rest initargs &key &allow-other-keys)
  (APPLY #'make-contact 'multiple-choices initargs))


(DEFMETHOD add-child :after ((choices multiple-choices) this-child &key)
  (flet
    (
     ;;; ===============================================================================
     ;;;
     ;;;       Our :changing and :canceling-change callback functions...
     ;;;
     (choices-changing (to-selected-p choices self)
       (DECLARE (IGNORE self))
       (LET((selection (choice-selection choices))
	    (default (choice-default choices)))

	 (WHEN default
	   ;; If there is a current choice default then we *may* have
	   ;; to temporarily inhibit display of the default ring.
	   (UNLESS (and selection to-selected-p)
	     ;; If there is a current selection already and we are
	     ;; transitioning *to* selected state then the default ring(s)
	     ;; are already inhibited.  Otherwise, there are two possibilites:
	     ;; (1) No selection, transitioning *to* selected.
	     ;;     We must inhibit ring display on all defaults.
	     ;; (2) Have selection, transitioning *from* selected.
	     ;;     If there is only one selection and it is transitioning to
	     ;;     unselected, then we must restore default ring(s) display.
	     (let
	       ((highlighted-p (not to-selected-p)))
	       (when (or to-selected-p (null (cdr selection)))
		 (DOLIST (item default)
		   (SETF (choice-item-highlight-default-p item) highlighted-p))))))))

     (choices-canceling-change (to-selected-p choices self)
       (DECLARE (IGNORE self))
       (LET((selection (choice-selection choices))
	    (default (choice-default choices)))

	 (WHEN default
	   ;; If we are canceling a transition to "selected" then we
	   ;; must restore the inhibited default ring display.
	   ;; If, on the other hand, we are canceling a transition
	   ;; back to "unselected" then we must once again inhibit
	   ;; default ring display.
	   (UNLESS (and selection to-selected-p)
	     ;; As in choices-changing, if there is a current selection
	     ;; already inhibiting default ring display then we need not
	     ;; restore display here.
	     (when (or to-selected-p (null (cdr selection)))
		 (DOLIST (item default)
		   (SETF (choice-item-highlight-default-p item) to-selected-p)))))))


     ;;; ================================================================================
     ;;;	This :off callback (destructively) removes the item from the current
     ;;;        selection set for this multiple-choices contact.
     ;;;
     (choices-off (choices self)
       (WITH-SLOTS (selection) choices
	 (WHEN selection (SETF selection (DELETE self selection)))))

     ;;; ================================================================================
     ;;;	This :on callback adds the item to the current selection set
     ;;;        for this multiple-choices contact.
     ;;;
     (choices-on (choices self)
       (WITH-SLOTS (selection) choices
	 ;; It is important to *not* use the SETF method here since doing so would
	 ;; potentially cause a loop. [SETF method invokes this callback!]
	 (SETF selection (cons self selection))))
     )						; ... end of flet ...

    (let((font (choice-font choices)))
      (WHEN font (SETF (choice-item-font this-child) font)))

    ;;  =====================================================================================
    ;;  If this child's name is on the default-selection list, replace it with this child.
    ;;
    (with-slots (default) choices
      (DO ((defaults default (REST defaults)))
	  ((NULL defaults))
	(WHEN (EQ (FIRST defaults) (contact-name this-child))
	  (RPLACA defaults this-child)
	  (SETF (choice-item-highlight-default-p this-child) T)
	  (RETURN))))

    (add-callback this-child :changing #'choices-changing choices this-child)
    (add-callback this-child :canceling-change #'choices-canceling-change choices this-child)
    (add-callback this-child :on #'choices-on choices this-child)
    (add-callback this-child :off #'choices-off choices this-child)))


;;; ===============================================================================
;;;
;;;              Method to set the default choice item set
;;;

(DEFMETHOD (SETF choice-default) (new-default-choice-items (choices multiple-choices))
  (with-slots (default children) choices
    (let
      ((new-defaults (set-difference new-default-choice-items default))
       (no-longer-defaults (set-difference default new-default-choice-items)))
      (WHEN new-defaults
	(ASSERT (subsetp new-defaults children)
		NIL
		"New default choice-items ~a are not children of ~a."
		(set-difference new-defaults children) choices)
	
	(DOLIST (item new-defaults)
	  (SETF (choice-item-highlight-default-p item) T))
	(DOLIST (item no-longer-defaults)
	  (SETF (choice-item-highlight-default-p item) NIL))
	(SETF default new-default-choice-items))))
  new-default-choice-items)


;;; ===============================================================================
;;;
;;;            Methods to set the selected choice-items set
;;;
(DEFMETHOD (SETF choice-selection) (children-to-be-selected (choices multiple-choices))

  (DECLARE (TYPE list children-to-be-selected))
  
  (with-slots (children selection) choices
    (let
      ((new-selections (set-difference children-to-be-selected selection))
       (no-longer-selected (set-difference selection children-to-be-selected)))
    
    ;;  Make sure the caller's selection are indeed a children of ours...
    (ASSERT (subsetp new-selections children)
	    NIL
      "Selections ~a are not children of ~a." (set-difference new-selections selection) choices)

    ;; Clear selected status of items no longer selected
    (DOLIST (item no-longer-selected)
      (SETF (choice-item-selected-p item) NIL))
    ;; Set selected status of items newly selected
    (DOLIST (item new-selections)
      (SETF (choice-item-selected-p item) T))))
  children-to-be-selected)

;;; ===============================================================================
;;;
;;;                   Method to force the font of all children...
;;;

(DEFMETHOD (SETF choice-font) (new-value (multiple-choices multiple-choices))
  
  (with-slots (children font) multiple-choices
    (if new-value
	(progn
	  (SETF font (find-font multiple-choices new-value))
	  (DOLIST (child children)
	    (SETF (choice-item-font child) new-value)))
	(SETF font NIL))
    new-value))