Mercurial > hg > xemacs-beta
diff 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 |
line wrap: on
line diff
--- a/lisp/custom/wid-edit.el Mon Aug 13 09:21:56 2007 +0200 +++ b/lisp/custom/wid-edit.el Mon Aug 13 09:23:06 2007 +0200 @@ -4,7 +4,7 @@ ;; ;; Author: Per Abrahamsen <abraham@dina.kvl.dk> ;; Keywords: extensions -;; Version: 1.65 +;; Version: 1.68 ;; X-URL: http://www.dina.kvl.dk/~abraham/custom/ ;;; Commentary: @@ -24,6 +24,9 @@ (autoload 'pp-to-string "pp") (autoload 'Info-goto-node "info") + (when (string-match "XEmacs" emacs-version) + (require 'overlay)) + (if (string-match "XEmacs" emacs-version) ;; XEmacs spell `intangible' as `atomic'. (defun widget-make-intangible (from to side) @@ -380,6 +383,41 @@ (goto-char (point-max)) result))) +(defface widget-inactive-face '((((class grayscale color) + (background dark)) + (:foreground "light gray")) + (((class grayscale color) + (background light)) + (:foreground "dark gray")) + (t + (:italic t))) + "Face used for inactive widgets." + :group 'widgets) + +(defun widget-specify-inactive (widget from to) + "Make WIDGET inactive for user modifications." + (unless (widget-get widget :inactive) + (let ((overlay (make-overlay from to nil t nil))) + (overlay-put overlay 'face 'widget-inactive-face) + (overlay-put overlay 'evaporate 't) + (overlay-put overlay (if (string-match "XEmacs" emacs-version) + 'read-only + 'modification-hooks) '(widget-overlay-inactive)) + (widget-put widget :inactive overlay)))) + +(defun widget-overlay-inactive (&rest junk) + "Ignoring the arguments, signal an error." + (unless inhibit-read-only + (error "Attempt to modify inactive widget"))) + + +(defun widget-specify-active (widget) + "Make WIDGET active for user modifications." + (let ((inactive (widget-get widget :inactive))) + (when inactive + (delete-overlay inactive) + (widget-put widget :inactive nil)))) + ;;; Widget Properties. (defsubst widget-type (widget) @@ -440,6 +478,12 @@ (cons (list (car vals)) (cdr vals))) (t nil))) +(defun widget-apply-action (widget &optional event) + "Apply :action in WIDGET in response to EVENT." + (if (widget-apply widget :active) + (widget-apply widget :action event) + (error "Attempt to perform action on inactive widget"))) + ;;; Glyphs. (defcustom widget-glyph-directory (concat data-directory "custom/") @@ -659,7 +703,7 @@ (interactive "@d") (let ((field (get-text-property pos 'field))) (if field - (widget-apply field :action event) + (widget-apply-action field event) (call-interactively (lookup-key widget-global-map (this-command-keys)))))) @@ -670,12 +714,12 @@ (event-glyph event)) (let ((widget (glyph-property (event-glyph event) 'widget))) (if widget - (widget-apply widget :action event) + (widget-apply-action widget event) (message "You clicked on a glyph.")))) ((event-point event) (let ((button (get-text-property (event-point event) 'button))) (if button - (widget-apply button :action event) + (widget-apply-action button event) (call-interactively (or (lookup-key widget-global-map [ button2 ]) (lookup-key widget-global-map [ down-mouse-2 ]) @@ -690,7 +734,7 @@ (event-glyph event)) (let ((widget (glyph-property (event-glyph event) 'widget))) (if widget - (widget-apply widget :action event) + (widget-apply-action widget event) (message "You clicked on a glyph."))) (call-interactively (lookup-key widget-global-map (this-command-keys))))) @@ -699,7 +743,7 @@ (interactive "@d") (let ((button (get-text-property pos 'button))) (if button - (widget-apply button :action event) + (widget-apply-action button event) (let ((command (lookup-key widget-global-map (this-command-keys)))) (when (commandp command) (call-interactively command)))))) @@ -947,6 +991,9 @@ :value-inline 'widget-default-value-inline :menu-tag-get 'widget-default-menu-tag-get :validate (lambda (widget) nil) + :active 'widget-default-active + :activate 'widget-specify-active + :deactivate 'widget-default-deactivate :action 'widget-default-action :notify 'widget-default-notify) @@ -1077,7 +1124,9 @@ (inhibit-read-only t) after-change-functions) (widget-apply widget :value-delete) - (delete-region from to) + (when (< from to) + ;; Kludge: this doesn't need to be true for empty formats. + (delete-region from to)) (set-marker from nil) (set-marker to nil))) @@ -1101,6 +1150,19 @@ (widget-get widget :tag) (widget-princ-to-string (widget-get widget :value)))) +(defun widget-default-active (widget) + "Return t iff this widget active (user modifiable)." + (and (not (widget-get widget :inactive)) + (let ((parent (widget-get widget :parent))) + (or (null parent) + (widget-apply parent :active))))) + +(defun widget-default-deactivate (widget) + "Make WIDGET inactive for user modifications." + (widget-specify-inactive widget + (widget-get widget :from) + (widget-get widget :to))) + (defun widget-default-action (widget &optional event) ;; Notify the parent when a widget change (let ((parent (widget-get widget :parent))) @@ -1196,7 +1258,7 @@ (defun widget-gui-action (widget) "Apply :action for WIDGET." - (widget-apply widget :action (this-command-keys))) + (widget-apply-action widget (this-command-keys))) ;;; The `link' Widget. @@ -1492,7 +1554,17 @@ :on "[X]" :on-glyph "check1" :off "[ ]" - :off-glyph "check0") + :off-glyph "check0" + :action 'widget-checkbox-action) + +(defun widget-checkbox-action (widget &optional event) + "Toggle checkbox, notify parent, and set active state of sibling." + (widget-toggle-action widget event) + (let ((sibling (widget-get-sibling widget))) + (when sibling + (if (widget-value widget) + (widget-apply sibling :activate) + (widget-apply sibling :deactivate))))) ;;; The `checklist' Widget. @@ -1549,7 +1621,9 @@ ((eq escape ?v) (setq child (cond ((not chosen) - (widget-create-child widget type)) + (let ((child (widget-create-child widget type))) + (widget-apply child :deactivate) + child)) ((widget-get type :inline) (widget-create-child-value widget type (cdr chosen))) @@ -1735,7 +1809,9 @@ (setq child (if chosen (widget-create-child-value widget type value) - (widget-create-child widget type)))) + (widget-create-child widget type))) + (unless chosen + (widget-apply child :deactivate))) (t (error "Unknown escape `%c'" escape))))) ;; Update properties. @@ -1795,7 +1871,10 @@ (widget-apply current :match value)))) (widget-value-set button match) (if match - (widget-value-set current value)) + (progn + (widget-value-set current value) + (widget-apply current :activate)) + (widget-apply current :deactivate)) (setq found (or found match)))))) (defun widget-radio-validate (widget) @@ -1822,9 +1901,11 @@ children (cdr children)) (let* ((button (widget-get current :button))) (cond ((eq child button) - (widget-value-set button t)) + (widget-value-set button t) + (widget-apply current :activate)) ((widget-value button) - (widget-value-set button nil))))))) + (widget-value-set button nil) + (widget-apply current :deactivate))))))) ;; Pass notification to parent. (widget-apply widget :notify child event)) @@ -1967,7 +2048,7 @@ (setq children (cdr children))) (setcdr children (cons child (cdr children))))))) (widget-setup) - (widget-apply widget :notify widget)) + widget (widget-apply widget :notify widget)) (defun widget-editable-list-delete-at (widget child) ;; Delete child from list of children.