Mercurial > hg > xemacs-beta
comparison lisp/custom/wid-edit.el @ 116:9f59509498e1 r20-1b10
Import from CVS: tag r20-1b10
author | cvs |
---|---|
date | Mon, 13 Aug 2007 09:23:06 +0200 |
parents | c53a95d3c46d |
children | 7d55a9ba150c |
comparison
equal
deleted
inserted
replaced
115:f109f7dabbe2 | 116:9f59509498e1 |
---|---|
2 ;; | 2 ;; |
3 ;; Copyright (C) 1996, 1997 Free Software Foundation, Inc. | 3 ;; Copyright (C) 1996, 1997 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.65 | 7 ;; Version: 1.68 |
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'. |
22 | 22 |
23 (eval-and-compile | 23 (eval-and-compile |
24 (autoload 'pp-to-string "pp") | 24 (autoload 'pp-to-string "pp") |
25 (autoload 'Info-goto-node "info") | 25 (autoload 'Info-goto-node "info") |
26 | 26 |
27 (when (string-match "XEmacs" emacs-version) | |
28 (require 'overlay)) | |
29 | |
27 (if (string-match "XEmacs" emacs-version) | 30 (if (string-match "XEmacs" emacs-version) |
28 ;; XEmacs spell `intangible' as `atomic'. | 31 ;; XEmacs spell `intangible' as `atomic'. |
29 (defun widget-make-intangible (from to side) | 32 (defun widget-make-intangible (from to side) |
30 "Make text between FROM and TO atomic with regard to movement. | 33 "Make text between FROM and TO atomic with regard to movement. |
31 Third argument should be `start-open' if it should be sticky to the rear, | 34 Third argument should be `start-open' if it should be sticky to the rear, |
378 (delete-region (point-min) (1+ (point-min))) | 381 (delete-region (point-min) (1+ (point-min))) |
379 (delete-region (1- (point-max)) (point-max)) | 382 (delete-region (1- (point-max)) (point-max)) |
380 (goto-char (point-max)) | 383 (goto-char (point-max)) |
381 result))) | 384 result))) |
382 | 385 |
386 (defface widget-inactive-face '((((class grayscale color) | |
387 (background dark)) | |
388 (:foreground "light gray")) | |
389 (((class grayscale color) | |
390 (background light)) | |
391 (:foreground "dark gray")) | |
392 (t | |
393 (:italic t))) | |
394 "Face used for inactive widgets." | |
395 :group 'widgets) | |
396 | |
397 (defun widget-specify-inactive (widget from to) | |
398 "Make WIDGET inactive for user modifications." | |
399 (unless (widget-get widget :inactive) | |
400 (let ((overlay (make-overlay from to nil t nil))) | |
401 (overlay-put overlay 'face 'widget-inactive-face) | |
402 (overlay-put overlay 'evaporate 't) | |
403 (overlay-put overlay (if (string-match "XEmacs" emacs-version) | |
404 'read-only | |
405 'modification-hooks) '(widget-overlay-inactive)) | |
406 (widget-put widget :inactive overlay)))) | |
407 | |
408 (defun widget-overlay-inactive (&rest junk) | |
409 "Ignoring the arguments, signal an error." | |
410 (unless inhibit-read-only | |
411 (error "Attempt to modify inactive widget"))) | |
412 | |
413 | |
414 (defun widget-specify-active (widget) | |
415 "Make WIDGET active for user modifications." | |
416 (let ((inactive (widget-get widget :inactive))) | |
417 (when inactive | |
418 (delete-overlay inactive) | |
419 (widget-put widget :inactive nil)))) | |
420 | |
383 ;;; Widget Properties. | 421 ;;; Widget Properties. |
384 | 422 |
385 (defsubst widget-type (widget) | 423 (defsubst widget-type (widget) |
386 "Return the type of WIDGET, a symbol." | 424 "Return the type of WIDGET, a symbol." |
387 (car widget)) | 425 (car widget)) |
438 ((and vals | 476 ((and vals |
439 (widget-apply widget :match (car vals))) | 477 (widget-apply widget :match (car vals))) |
440 (cons (list (car vals)) (cdr vals))) | 478 (cons (list (car vals)) (cdr vals))) |
441 (t nil))) | 479 (t nil))) |
442 | 480 |
481 (defun widget-apply-action (widget &optional event) | |
482 "Apply :action in WIDGET in response to EVENT." | |
483 (if (widget-apply widget :active) | |
484 (widget-apply widget :action event) | |
485 (error "Attempt to perform action on inactive widget"))) | |
486 | |
443 ;;; Glyphs. | 487 ;;; Glyphs. |
444 | 488 |
445 (defcustom widget-glyph-directory (concat data-directory "custom/") | 489 (defcustom widget-glyph-directory (concat data-directory "custom/") |
446 "Where widget glyphs are located. | 490 "Where widget glyphs are located. |
447 If this variable is nil, widget will try to locate the directory | 491 If this variable is nil, widget will try to locate the directory |
657 (defun widget-field-activate (pos &optional event) | 701 (defun widget-field-activate (pos &optional event) |
658 "Activate the ediable field at point." | 702 "Activate the ediable field at point." |
659 (interactive "@d") | 703 (interactive "@d") |
660 (let ((field (get-text-property pos 'field))) | 704 (let ((field (get-text-property pos 'field))) |
661 (if field | 705 (if field |
662 (widget-apply field :action event) | 706 (widget-apply-action field event) |
663 (call-interactively | 707 (call-interactively |
664 (lookup-key widget-global-map (this-command-keys)))))) | 708 (lookup-key widget-global-map (this-command-keys)))))) |
665 | 709 |
666 (defun widget-button-click (event) | 710 (defun widget-button-click (event) |
667 "Activate button below mouse pointer." | 711 "Activate button below mouse pointer." |
668 (interactive "@e") | 712 (interactive "@e") |
669 (cond ((and (fboundp 'event-glyph) | 713 (cond ((and (fboundp 'event-glyph) |
670 (event-glyph event)) | 714 (event-glyph event)) |
671 (let ((widget (glyph-property (event-glyph event) 'widget))) | 715 (let ((widget (glyph-property (event-glyph event) 'widget))) |
672 (if widget | 716 (if widget |
673 (widget-apply widget :action event) | 717 (widget-apply-action widget event) |
674 (message "You clicked on a glyph.")))) | 718 (message "You clicked on a glyph.")))) |
675 ((event-point event) | 719 ((event-point event) |
676 (let ((button (get-text-property (event-point event) 'button))) | 720 (let ((button (get-text-property (event-point event) 'button))) |
677 (if button | 721 (if button |
678 (widget-apply button :action event) | 722 (widget-apply-action button event) |
679 (call-interactively | 723 (call-interactively |
680 (or (lookup-key widget-global-map [ button2 ]) | 724 (or (lookup-key widget-global-map [ button2 ]) |
681 (lookup-key widget-global-map [ down-mouse-2 ]) | 725 (lookup-key widget-global-map [ down-mouse-2 ]) |
682 (lookup-key widget-global-map [ mouse-2])))))) | 726 (lookup-key widget-global-map [ mouse-2])))))) |
683 (t | 727 (t |
688 (interactive "@e") | 732 (interactive "@e") |
689 (if (and (fboundp 'event-glyph) | 733 (if (and (fboundp 'event-glyph) |
690 (event-glyph event)) | 734 (event-glyph event)) |
691 (let ((widget (glyph-property (event-glyph event) 'widget))) | 735 (let ((widget (glyph-property (event-glyph event) 'widget))) |
692 (if widget | 736 (if widget |
693 (widget-apply widget :action event) | 737 (widget-apply-action widget event) |
694 (message "You clicked on a glyph."))) | 738 (message "You clicked on a glyph."))) |
695 (call-interactively (lookup-key widget-global-map (this-command-keys))))) | 739 (call-interactively (lookup-key widget-global-map (this-command-keys))))) |
696 | 740 |
697 (defun widget-button-press (pos &optional event) | 741 (defun widget-button-press (pos &optional event) |
698 "Activate button at POS." | 742 "Activate button at POS." |
699 (interactive "@d") | 743 (interactive "@d") |
700 (let ((button (get-text-property pos 'button))) | 744 (let ((button (get-text-property pos 'button))) |
701 (if button | 745 (if button |
702 (widget-apply button :action event) | 746 (widget-apply-action button event) |
703 (let ((command (lookup-key widget-global-map (this-command-keys)))) | 747 (let ((command (lookup-key widget-global-map (this-command-keys)))) |
704 (when (commandp command) | 748 (when (commandp command) |
705 (call-interactively command)))))) | 749 (call-interactively command)))))) |
706 | 750 |
707 (defun widget-move (arg) | 751 (defun widget-move (arg) |
945 :delete 'widget-default-delete | 989 :delete 'widget-default-delete |
946 :value-set 'widget-default-value-set | 990 :value-set 'widget-default-value-set |
947 :value-inline 'widget-default-value-inline | 991 :value-inline 'widget-default-value-inline |
948 :menu-tag-get 'widget-default-menu-tag-get | 992 :menu-tag-get 'widget-default-menu-tag-get |
949 :validate (lambda (widget) nil) | 993 :validate (lambda (widget) nil) |
994 :active 'widget-default-active | |
995 :activate 'widget-specify-active | |
996 :deactivate 'widget-default-deactivate | |
950 :action 'widget-default-action | 997 :action 'widget-default-action |
951 :notify 'widget-default-notify) | 998 :notify 'widget-default-notify) |
952 | 999 |
953 (defun widget-default-create (widget) | 1000 (defun widget-default-create (widget) |
954 "Create WIDGET at point in the current buffer." | 1001 "Create WIDGET at point in the current buffer." |
1075 (let ((from (widget-get widget :from)) | 1122 (let ((from (widget-get widget :from)) |
1076 (to (widget-get widget :to)) | 1123 (to (widget-get widget :to)) |
1077 (inhibit-read-only t) | 1124 (inhibit-read-only t) |
1078 after-change-functions) | 1125 after-change-functions) |
1079 (widget-apply widget :value-delete) | 1126 (widget-apply widget :value-delete) |
1080 (delete-region from to) | 1127 (when (< from to) |
1128 ;; Kludge: this doesn't need to be true for empty formats. | |
1129 (delete-region from to)) | |
1081 (set-marker from nil) | 1130 (set-marker from nil) |
1082 (set-marker to nil))) | 1131 (set-marker to nil))) |
1083 | 1132 |
1084 (defun widget-default-value-set (widget value) | 1133 (defun widget-default-value-set (widget value) |
1085 ;; Recreate widget with new value. | 1134 ;; Recreate widget with new value. |
1098 (defun widget-default-menu-tag-get (widget) | 1147 (defun widget-default-menu-tag-get (widget) |
1099 ;; Use tag or value for menus. | 1148 ;; Use tag or value for menus. |
1100 (or (widget-get widget :menu-tag) | 1149 (or (widget-get widget :menu-tag) |
1101 (widget-get widget :tag) | 1150 (widget-get widget :tag) |
1102 (widget-princ-to-string (widget-get widget :value)))) | 1151 (widget-princ-to-string (widget-get widget :value)))) |
1152 | |
1153 (defun widget-default-active (widget) | |
1154 "Return t iff this widget active (user modifiable)." | |
1155 (and (not (widget-get widget :inactive)) | |
1156 (let ((parent (widget-get widget :parent))) | |
1157 (or (null parent) | |
1158 (widget-apply parent :active))))) | |
1159 | |
1160 (defun widget-default-deactivate (widget) | |
1161 "Make WIDGET inactive for user modifications." | |
1162 (widget-specify-inactive widget | |
1163 (widget-get widget :from) | |
1164 (widget-get widget :to))) | |
1103 | 1165 |
1104 (defun widget-default-action (widget &optional event) | 1166 (defun widget-default-action (widget &optional event) |
1105 ;; Notify the parent when a widget change | 1167 ;; Notify the parent when a widget change |
1106 (let ((parent (widget-get widget :parent))) | 1168 (let ((parent (widget-get widget :parent))) |
1107 (when parent | 1169 (when parent |
1194 (make-glyph (car (aref gui 1))))) | 1256 (make-glyph (car (aref gui 1))))) |
1195 (insert text)))) | 1257 (insert text)))) |
1196 | 1258 |
1197 (defun widget-gui-action (widget) | 1259 (defun widget-gui-action (widget) |
1198 "Apply :action for WIDGET." | 1260 "Apply :action for WIDGET." |
1199 (widget-apply widget :action (this-command-keys))) | 1261 (widget-apply-action widget (this-command-keys))) |
1200 | 1262 |
1201 ;;; The `link' Widget. | 1263 ;;; The `link' Widget. |
1202 | 1264 |
1203 (define-widget 'link 'item | 1265 (define-widget 'link 'item |
1204 "An embedded link." | 1266 "An embedded link." |
1490 "A checkbox toggle." | 1552 "A checkbox toggle." |
1491 :format "%[%v%]" | 1553 :format "%[%v%]" |
1492 :on "[X]" | 1554 :on "[X]" |
1493 :on-glyph "check1" | 1555 :on-glyph "check1" |
1494 :off "[ ]" | 1556 :off "[ ]" |
1495 :off-glyph "check0") | 1557 :off-glyph "check0" |
1558 :action 'widget-checkbox-action) | |
1559 | |
1560 (defun widget-checkbox-action (widget &optional event) | |
1561 "Toggle checkbox, notify parent, and set active state of sibling." | |
1562 (widget-toggle-action widget event) | |
1563 (let ((sibling (widget-get-sibling widget))) | |
1564 (when sibling | |
1565 (if (widget-value widget) | |
1566 (widget-apply sibling :activate) | |
1567 (widget-apply sibling :deactivate))))) | |
1496 | 1568 |
1497 ;;; The `checklist' Widget. | 1569 ;;; The `checklist' Widget. |
1498 | 1570 |
1499 (define-widget 'checklist 'default | 1571 (define-widget 'checklist 'default |
1500 "A multiple choice widget." | 1572 "A multiple choice widget." |
1547 :value (not (null chosen)) | 1619 :value (not (null chosen)) |
1548 button-args))) | 1620 button-args))) |
1549 ((eq escape ?v) | 1621 ((eq escape ?v) |
1550 (setq child | 1622 (setq child |
1551 (cond ((not chosen) | 1623 (cond ((not chosen) |
1552 (widget-create-child widget type)) | 1624 (let ((child (widget-create-child widget type))) |
1625 (widget-apply child :deactivate) | |
1626 child)) | |
1553 ((widget-get type :inline) | 1627 ((widget-get type :inline) |
1554 (widget-create-child-value | 1628 (widget-create-child-value |
1555 widget type (cdr chosen))) | 1629 widget type (cdr chosen))) |
1556 (t | 1630 (t |
1557 (widget-create-child-value | 1631 (widget-create-child-value |
1733 button-args))) | 1807 button-args))) |
1734 ((eq escape ?v) | 1808 ((eq escape ?v) |
1735 (setq child (if chosen | 1809 (setq child (if chosen |
1736 (widget-create-child-value | 1810 (widget-create-child-value |
1737 widget type value) | 1811 widget type value) |
1738 (widget-create-child widget type)))) | 1812 (widget-create-child widget type))) |
1813 (unless chosen | |
1814 (widget-apply child :deactivate))) | |
1739 (t | 1815 (t |
1740 (error "Unknown escape `%c'" escape))))) | 1816 (error "Unknown escape `%c'" escape))))) |
1741 ;; Update properties. | 1817 ;; Update properties. |
1742 (when chosen | 1818 (when chosen |
1743 (widget-put widget :choice type)) | 1819 (widget-put widget :choice type)) |
1793 (let* ((button (widget-get current :button)) | 1869 (let* ((button (widget-get current :button)) |
1794 (match (and (not found) | 1870 (match (and (not found) |
1795 (widget-apply current :match value)))) | 1871 (widget-apply current :match value)))) |
1796 (widget-value-set button match) | 1872 (widget-value-set button match) |
1797 (if match | 1873 (if match |
1798 (widget-value-set current value)) | 1874 (progn |
1875 (widget-value-set current value) | |
1876 (widget-apply current :activate)) | |
1877 (widget-apply current :deactivate)) | |
1799 (setq found (or found match)))))) | 1878 (setq found (or found match)))))) |
1800 | 1879 |
1801 (defun widget-radio-validate (widget) | 1880 (defun widget-radio-validate (widget) |
1802 ;; Valid if we have made a valid choice. | 1881 ;; Valid if we have made a valid choice. |
1803 (let ((children (widget-get widget :children)) | 1882 (let ((children (widget-get widget :children)) |
1820 (while children | 1899 (while children |
1821 (setq current (car children) | 1900 (setq current (car children) |
1822 children (cdr children)) | 1901 children (cdr children)) |
1823 (let* ((button (widget-get current :button))) | 1902 (let* ((button (widget-get current :button))) |
1824 (cond ((eq child button) | 1903 (cond ((eq child button) |
1825 (widget-value-set button t)) | 1904 (widget-value-set button t) |
1905 (widget-apply current :activate)) | |
1826 ((widget-value button) | 1906 ((widget-value button) |
1827 (widget-value-set button nil))))))) | 1907 (widget-value-set button nil) |
1908 (widget-apply current :deactivate))))))) | |
1828 ;; Pass notification to parent. | 1909 ;; Pass notification to parent. |
1829 (widget-apply widget :notify child event)) | 1910 (widget-apply widget :notify child event)) |
1830 | 1911 |
1831 ;;; The `insert-button' Widget. | 1912 ;;; The `insert-button' Widget. |
1832 | 1913 |
1965 (widget-put widget :children (cons child children)) | 2046 (widget-put widget :children (cons child children)) |
1966 (while (not (eq (car (cdr children)) before)) | 2047 (while (not (eq (car (cdr children)) before)) |
1967 (setq children (cdr children))) | 2048 (setq children (cdr children))) |
1968 (setcdr children (cons child (cdr children))))))) | 2049 (setcdr children (cons child (cdr children))))))) |
1969 (widget-setup) | 2050 (widget-setup) |
1970 (widget-apply widget :notify widget)) | 2051 widget (widget-apply widget :notify widget)) |
1971 | 2052 |
1972 (defun widget-editable-list-delete-at (widget child) | 2053 (defun widget-editable-list-delete-at (widget child) |
1973 ;; Delete child from list of children. | 2054 ;; Delete child from list of children. |
1974 (save-excursion | 2055 (save-excursion |
1975 (let ((buttons (copy-list (widget-get widget :buttons))) | 2056 (let ((buttons (copy-list (widget-get widget :buttons))) |