Mercurial > hg > xemacs-beta
comparison lisp/custom/widget-edit.el @ 20:859a2309aef8 r19-15b93
Import from CVS: tag r19-15b93
author | cvs |
---|---|
date | Mon, 13 Aug 2007 08:50:05 +0200 |
parents | d95e72db5c07 |
children | 8fc7fe29b841 |
comparison
equal
deleted
inserted
replaced
19:ac1f612d5250 | 20:859a2309aef8 |
---|---|
2 ;; | 2 ;; |
3 ;; Copyright (C) 1996 Free Software Foundation, Inc. | 3 ;; Copyright (C) 1996 Free Software Foundation, Inc. |
4 ;; | 4 ;; |
5 ;; Author: Per Abrahamsen <abraham@dina.kvl.dk> | 5 ;; Author: Per Abrahamsen <abraham@dina.kvl.dk> |
6 ;; Keywords: extensions | 6 ;; Keywords: extensions |
7 ;; Version: 1.24 | 7 ;; Version: 1.30 |
8 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ | 8 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ |
9 | 9 |
10 ;;; Commentary: | 10 ;;; Commentary: |
11 ;; | 11 ;; |
12 ;; See `widget.el'. | 12 ;; See `widget.el'. |
188 (t | 188 (t |
189 (cdr (assoc (completing-read (concat title ": ") | 189 (cdr (assoc (completing-read (concat title ": ") |
190 items nil t) | 190 items nil t) |
191 items))))) | 191 items))))) |
192 | 192 |
193 (defun widget-get-sibling (widget) | |
194 "Get the item WIDGET is assumed to toggle. | |
195 This is only meaningful for radio buttons or checkboxes in a list." | |
196 (let* ((parent (widget-get widget :parent)) | |
197 (children (widget-get parent :children)) | |
198 child) | |
199 (catch 'child | |
200 (while children | |
201 (setq child (car children) | |
202 children (cdr children)) | |
203 (when (eq (widget-get child :button) widget) | |
204 (throw 'child child))) | |
205 nil))) | |
206 | |
193 ;;; Widget text specifications. | 207 ;;; Widget text specifications. |
194 ;; | 208 ;; |
195 ;; These functions are for specifying text properties. | 209 ;; These functions are for specifying text properties. |
196 | 210 |
197 (defun widget-specify-none (from to) | 211 (defun widget-specify-none (from to) |
286 (put-text-property (point) (1+ (point)) 'secret old)) | 300 (put-text-property (point) (1+ (point)) 'secret old)) |
287 (forward-char)))) | 301 (forward-char)))) |
288 | 302 |
289 (unless (widget-get widget :size) | 303 (unless (widget-get widget :size) |
290 (add-text-properties to (1+ to) (list 'field widget | 304 (add-text-properties to (1+ to) (list 'field widget |
291 'face face | 305 'face face))) |
292 'local-map map | 306 (add-text-properties to (1+ to) (list 'local-map map |
293 'keymap map))))) | 307 'keymap map)))) |
294 | 308 |
295 (defun widget-specify-button (widget from to) | 309 (defun widget-specify-button (widget from to) |
296 ;; Specify button for WIDGET between FROM and TO. | 310 ;; Specify button for WIDGET between FROM and TO. |
297 (let ((face (widget-apply widget :button-face-get))) | 311 (let ((face (widget-apply widget :button-face-get))) |
298 (add-text-properties from to (list 'button widget | 312 (add-text-properties from to (list 'button widget |
329 (delete-region (1- (point-max)) (point-max)) | 343 (delete-region (1- (point-max)) (point-max)) |
330 (goto-char (point-max)) | 344 (goto-char (point-max)) |
331 result))) | 345 result))) |
332 | 346 |
333 ;;; Widget Properties. | 347 ;;; Widget Properties. |
348 | |
349 (defsubst widget-name (widget) | |
350 "Return the name of WIDGET, asymbol." | |
351 (car widget)) | |
334 | 352 |
335 (defun widget-put (widget property value) | 353 (defun widget-put (widget property value) |
336 "In WIDGET set PROPERTY to VALUE. | 354 "In WIDGET set PROPERTY to VALUE. |
337 The value can later be retrived with `widget-get'." | 355 The value can later be retrived with `widget-get'." |
338 (setcdr widget (plist-put (cdr widget) property value))) | 356 (setcdr widget (plist-put (cdr widget) property value))) |
489 "Keymap containing useful binding for buffers containing widgets. | 507 "Keymap containing useful binding for buffers containing widgets. |
490 Recommended as a parent keymap for modes using widgets.") | 508 Recommended as a parent keymap for modes using widgets.") |
491 | 509 |
492 (unless widget-keymap | 510 (unless widget-keymap |
493 (setq widget-keymap (make-sparse-keymap)) | 511 (setq widget-keymap (make-sparse-keymap)) |
512 (define-key widget-keymap "\C-k" 'widget-kill-line) | |
494 (define-key widget-keymap "\t" 'widget-forward) | 513 (define-key widget-keymap "\t" 'widget-forward) |
495 (define-key widget-keymap "\M-\t" 'widget-backward) | 514 (define-key widget-keymap "\M-\t" 'widget-backward) |
496 (define-key widget-keymap [(shift tab)] 'widget-backward) | 515 (define-key widget-keymap [(shift tab)] 'widget-backward) |
497 (define-key widget-keymap [(shift tab)] 'widget-backward) | 516 (define-key widget-keymap [(shift tab)] 'widget-backward) |
498 (define-key widget-keymap [backtab] 'widget-backward) | 517 (define-key widget-keymap [backtab] 'widget-backward) |
510 "Keymap used inside an editable field.") | 529 "Keymap used inside an editable field.") |
511 | 530 |
512 (unless widget-field-keymap | 531 (unless widget-field-keymap |
513 (setq widget-field-keymap (copy-keymap widget-keymap)) | 532 (setq widget-field-keymap (copy-keymap widget-keymap)) |
514 (define-key widget-field-keymap "\C-m" 'widget-field-activate) | 533 (define-key widget-field-keymap "\C-m" 'widget-field-activate) |
534 (define-key widget-field-keymap "\C-a" 'widget-beginning-of-line) | |
535 (define-key widget-field-keymap "\C-e" 'widget-end-of-line) | |
515 (set-keymap-parent widget-field-keymap global-map)) | 536 (set-keymap-parent widget-field-keymap global-map)) |
516 | 537 |
517 (defvar widget-text-keymap nil | 538 (defvar widget-text-keymap nil |
518 "Keymap used inside a text field.") | 539 "Keymap used inside a text field.") |
519 | 540 |
520 (unless widget-text-keymap | 541 (unless widget-text-keymap |
521 (setq widget-text-keymap (copy-keymap widget-keymap)) | 542 (setq widget-text-keymap (copy-keymap widget-keymap)) |
543 (define-key widget-text-keymap "\C-a" 'widget-beginning-of-line) | |
544 (define-key widget-text-keymap "\C-e" 'widget-end-of-line) | |
522 (set-keymap-parent widget-text-keymap global-map)) | 545 (set-keymap-parent widget-text-keymap global-map)) |
523 | 546 |
524 (defun widget-field-activate (pos &optional event) | 547 (defun widget-field-activate (pos &optional event) |
525 "Activate the ediable field at point." | 548 "Activate the ediable field at point." |
526 (interactive "@d") | 549 (interactive "@d") |
623 With optional ARG, move across that many fields." | 646 With optional ARG, move across that many fields." |
624 (interactive "p") | 647 (interactive "p") |
625 (run-hooks 'widget-backward-hook) | 648 (run-hooks 'widget-backward-hook) |
626 (widget-move (- arg))) | 649 (widget-move (- arg))) |
627 | 650 |
651 (defun widget-beginning-of-line () | |
652 "Go to beginning of field or beginning of line, whichever is first." | |
653 (interactive) | |
654 (let ((bol (save-excursion (beginning-of-line) (point))) | |
655 (prev (previous-single-property-change (point) 'field))) | |
656 (goto-char (max bol (or prev bol))))) | |
657 | |
658 (defun widget-end-of-line () | |
659 "Go to end of field or end of line, whichever is first." | |
660 (interactive) | |
661 (let ((bol (save-excursion (end-of-line) (point))) | |
662 (prev (next-single-property-change (point) 'field))) | |
663 (goto-char (min bol (or prev bol))))) | |
664 | |
665 (defun widget-kill-line () | |
666 "Kill to end of field or end of line, whichever is first." | |
667 (interactive) | |
668 (let ((field (get-text-property (point) 'field)) | |
669 (newline (save-excursion (search-forward "\n"))) | |
670 (next (next-single-property-change (point) 'field))) | |
671 (if (and field (> newline next)) | |
672 (kill-region (point) next) | |
673 (call-interactively 'kill-line)))) | |
674 | |
675 (defun widget-identify (pos) | |
676 "Identify the widget under point." | |
677 (interactive "d") | |
678 (let* ((field (get-text-property pos 'field)) | |
679 (button (get-text-property pos 'button)) | |
680 (doc (get-text-property pos 'widget-doc)) | |
681 (widget (or field button doc))) | |
682 (with-output-to-temp-buffer "*Widget Identity*" | |
683 (princ (cond (field "This is an editable text area.\n") | |
684 (button "This is an active area.\n") | |
685 (doc "This is documentation text.\n") | |
686 (t "This is unidentified text.\n"))) | |
687 (while widget | |
688 (princ "It is part of a `") | |
689 (princ (car widget)) | |
690 (princ "' widget (value: ") | |
691 (prin1 (condition-case nil | |
692 (widget-value widget) | |
693 (error 'error))) | |
694 (princ ").\n") | |
695 (when (eq (car widget) 'radio-button) | |
696 (let ((sibling (widget-get-sibling widget))) | |
697 (if (not sibling) | |
698 (princ "It doesn't seem to control anything.\n") | |
699 (princ "The value of its sibling is: ") | |
700 (prin1 (condition-case nil | |
701 (widget-value sibling) | |
702 (error 'error))) | |
703 (princ ".\n")))) | |
704 (setq widget (widget-get widget :parent)))))) | |
705 | |
628 ;;; Setting up the buffer. | 706 ;;; Setting up the buffer. |
629 | 707 |
630 (defvar widget-field-new nil) | 708 (defvar widget-field-new nil) |
631 ;; List of all newly created editable fields in the buffer. | 709 ;; List of all newly created editable fields in the buffer. |
632 (make-variable-buffer-local 'widget-field-new) | 710 (make-variable-buffer-local 'widget-field-new) |
1229 found (widget-match-inline current values))) | 1307 found (widget-match-inline current values))) |
1230 found)) | 1308 found)) |
1231 | 1309 |
1232 ;;; The `toggle' Widget. | 1310 ;;; The `toggle' Widget. |
1233 | 1311 |
1234 (define-widget 'toggle 'menu-choice | 1312 (define-widget 'toggle 'item |
1235 "Toggle between two states." | 1313 "Toggle between two states." |
1236 :convert-widget 'widget-toggle-convert-widget | 1314 :format "%[%v%]\n" |
1237 :format "%v" | 1315 :value-create 'widget-toggle-value-create |
1316 :action 'widget-toggle-action | |
1317 :match (lambda (widget value) t) | |
1238 :on "on" | 1318 :on "on" |
1239 :off "off") | 1319 :off "off") |
1240 | 1320 |
1241 (defun widget-toggle-convert-widget (widget) | 1321 (defun widget-toggle-value-create (widget) |
1242 ;; Create the types representing the `on' and `off' states. | 1322 ;; Insert text representing the `on' and `off' states. |
1243 (let ((on-type (widget-get widget :on-type)) | 1323 (if (widget-value widget) |
1244 (off-type (widget-get widget :off-type))) | 1324 (insert (widget-get widget :on)) |
1245 (unless on-type | 1325 (insert (widget-get widget :off)))) |
1246 (setq on-type | 1326 |
1247 (list 'choice-item | 1327 (defun widget-toggle-action (widget &optional event) |
1248 :value t | 1328 ;; Toggle value. |
1249 :match (lambda (widget value) value) | 1329 (widget-value-set widget (not (widget-value widget))) |
1250 :tag (widget-get widget :on)))) | 1330 (widget-apply widget :notify widget event)) |
1251 (unless off-type | 1331 |
1252 (setq off-type | |
1253 (list 'choice-item :value nil :tag (widget-get widget :off)))) | |
1254 (widget-put widget :args (list on-type off-type))) | |
1255 widget) | |
1256 | |
1257 ;;; The `checkbox' Widget. | 1332 ;;; The `checkbox' Widget. |
1258 | 1333 |
1259 (define-widget 'checkbox 'toggle | 1334 (define-widget 'checkbox 'toggle |
1260 "A checkbox toggle." | 1335 "A checkbox toggle." |
1261 :convert-widget 'widget-item-convert-widget | 1336 :format "%[%v%]" |
1262 :on-type '(choice-item :format "%[[X]%]" t) | 1337 :on "[X]" |
1263 :off-type '(choice-item :format "%[[ ]%]" nil)) | 1338 :off "[ ]") |
1264 | 1339 |
1265 ;;; The `checklist' Widget. | 1340 ;;; The `checklist' Widget. |
1266 | 1341 |
1267 (define-widget 'checklist 'default | 1342 (define-widget 'checklist 'default |
1268 "A multiple choice widget." | 1343 "A multiple choice widget." |
1425 ;;; The `radio-button' Widget. | 1500 ;;; The `radio-button' Widget. |
1426 | 1501 |
1427 (define-widget 'radio-button 'toggle | 1502 (define-widget 'radio-button 'toggle |
1428 "A radio button for use in the `radio' widget." | 1503 "A radio button for use in the `radio' widget." |
1429 :notify 'widget-radio-button-notify | 1504 :notify 'widget-radio-button-notify |
1430 :on-type '(choice-item :format "%[(*)%]" t) | 1505 :format "%[%v%]" |
1431 :off-type '(choice-item :format "%[( )%]" nil)) | 1506 :on "(*)" |
1507 :off "( )") | |
1432 | 1508 |
1433 (defun widget-radio-button-notify (widget child &optional event) | 1509 (defun widget-radio-button-notify (widget child &optional event) |
1434 ;; Notify the parent. | 1510 ;; Tell daddy. |
1435 (widget-apply (widget-get widget :parent) :action widget event)) | 1511 (widget-apply (widget-get widget :parent) :action widget event)) |
1436 | 1512 |
1437 ;;; The `radio-button-choice' Widget. | 1513 ;;; The `radio-button-choice' Widget. |
1438 | 1514 |
1439 (define-widget 'radio-button-choice 'default | 1515 (define-widget 'radio-button-choice 'default |
2072 :format "%{%t%}:\n%v") | 2148 :format "%{%t%}:\n%v") |
2073 | 2149 |
2074 (define-widget 'boolean 'toggle | 2150 (define-widget 'boolean 'toggle |
2075 "To be nil or non-nil, that is the question." | 2151 "To be nil or non-nil, that is the question." |
2076 :tag "Boolean" | 2152 :tag "Boolean" |
2077 :format "%{%t%}: %v") | 2153 :format "%{%t%}: %[%v%]") |
2078 | 2154 |
2079 ;;; The `color' Widget. | 2155 ;;; The `color' Widget. |
2080 | 2156 |
2081 (define-widget 'color-item 'choice-item | 2157 (define-widget 'color-item 'choice-item |
2082 "A color name (with sample)." | 2158 "A color name (with sample)." |