aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Ponce2005-08-15 13:00:09 +0000
committerDavid Ponce2005-08-15 13:00:09 +0000
commit0cfce69f6e359aded65cb59eeab914767435c38e (patch)
tree3c5efcd33379845bc63d29bc16a4a8c36a919c9c
parent86ae23f8c48916016a2c34ba81ff0f7c2e75bfb1 (diff)
downloademacs-0cfce69f6e359aded65cb59eeab914767435c38e.tar.gz
emacs-0cfce69f6e359aded65cb59eeab914767435c38e.zip
Update Commentary header.
(tree-widget-theme): Doc fix. (tree-widget-space-width): New option. (tree-widget-image-properties): Look up in the default theme too. (tree-widget--cursors): Only for images with arrow pointer shape. (tree-widget-lookup-image): Pointer shape is hand by default. (tree-widget-icon): Generic icon widget renamed from `tree-widget-control'. (tree-widget-*-icon): Rename from `tree-widget-*-control' and derive from `tree-widget-icon'. (tree-widget-handle): Improve default look and feel of the text representation. (tree-widget): Rename :*-control properties to :*-icon properties. Add :action and :help-echo properties. (tree-widget-after-toggle-functions): Move. (tree-widget-close-node, tree-widget-open-node): Remove. (tree-widget-before-create-icon-functions): New hook. (tree-widget-value-create): Update to allow customization of icons and nodes at run-time via that new hook. (tree-widget-icon-create, tree-widget-leaf-node-icon-p) (tree-widget-icon-action, tree-widget-icon-help-echo) (tree-widget-action, tree-widget-help-echo): New functions.
-rw-r--r--lisp/tree-widget.el376
1 files changed, 235 insertions, 141 deletions
diff --git a/lisp/tree-widget.el b/lisp/tree-widget.el
index 407fb65ea49..049999a7b88 100644
--- a/lisp/tree-widget.el
+++ b/lisp/tree-widget.el
@@ -59,37 +59,52 @@
59;; values, it is necessary to set the :args property to nil, then 59;; values, it is necessary to set the :args property to nil, then
60;; redraw the tree. 60;; redraw the tree.
61;; 61;;
62;; :open-control (default `tree-widget-open-control') 62;; :open-icon (default `tree-widget-open-icon')
63;; :close-control (default `tree-widget-close-control') 63;; :close-icon (default `tree-widget-close-icon')
64;; :empty-control (default `tree-widget-empty-control') 64;; :empty-icon (default `tree-widget-empty-icon')
65;; :leaf-control (default `tree-widget-leaf-control') 65;; :leaf-icon (default `tree-widget-leaf-icon')
66;; :guide (default `tree-widget-guide') 66;; Those properties define the icon widgets associated to tree
67;; :end-guide (default `tree-widget-end-guide') 67;; nodes. Icon widgets must derive from the `tree-widget-icon'
68;; :no-guide (default `tree-widget-no-guide') 68;; widget. The :tag and :glyph-name property values are
69;; :handle (default `tree-widget-handle') 69;; respectively used when drawing the text and graphic
70;; :no-handle (default `tree-widget-no-handle') 70;; representation of the tree. The :tag value must be a string
71;; Those properties define the widgets used to draw the tree, and 71;; that represent a node icon, like "[+]" for example. The
72;; permit to customize its look and feel. For example, using 72;; :glyph-name value must the name of an image found in the current
73;; `item' widgets with these :tag values: 73;; theme, like "close" for example (see also the variable
74;; `tree-widget-theme').
74;; 75;;
75;; open-control "[-] " (OC) 76;; :guide (default `tree-widget-guide')
76;; close-control "[+] " (CC) 77;; :end-guide (default `tree-widget-end-guide')
77;; empty-control "[X] " (EC) 78;; :no-guide (default `tree-widget-no-guide')
78;; leaf-control "[>] " (LC) 79;; :handle (default `tree-widget-handle')
79;; guide " |" (GU) 80;; :no-handle (default `tree-widget-no-handle')
80;; noguide " " (NG) 81;; Those properties define `item'-like widgets used to draw the
81;; end-guide " `" (EG) 82;; tree guide lines. The :tag property value is used when drawing
82;; handle "-" (HA) 83;; the text representation of the tree. The graphic look and feel
83;; no-handle " " (NH) 84;; is given by the images named "guide", "no-guide", "end-guide",
85;; "handle", and "no-handle" found in the current theme (see also
86;; the variable `tree-widget-theme').
84;; 87;;
85;; A tree will look like this: 88;; These are the default :tag values for icons, and guide lines:
86;; 89;;
87;; [-] 1 (OC :node) 90;; open-icon "[-]"
88;; |-[+] 1.0 (GU+HA+CC :node) 91;; close-icon "[+]"
89;; |-[X] 1.1 (GU+HA+EC :node) 92;; empty-icon "[X]"
90;; `-[-] 1.2 (EG+HA+OC :node) 93;; leaf-icon ""
91;; |-[>] 1.2.1 (NG+NH+GU+HA+LC child) 94;; guide " |"
92;; `-[>] 1.2.2 (NG+NH+EG+HA+LC child) 95;; no-guide " "
96;; end-guide " `"
97;; handle "-"
98;; no-handle " "
99;;
100;; The text representation of a tree looks like this:
101;;
102;; [-] 1 (open-icon :node)
103;; |-[+] 1.0 (guide+handle+close-icon :node)
104;; |-[X] 1.1 (guide+handle+empty-icon :node)
105;; `-[-] 1.2 (end-guide+handle+open-icon :node)
106;; |- 1.2.1 (no-guide+no-handle+guide+handle+leaf-icon leaf)
107;; `- 1.2.2 (no-guide+no-handle+end-guide+handle+leaf-icon leaf)
93;; 108;;
94;; By default, images will be used instead of strings to draw a 109;; By default, images will be used instead of strings to draw a
95;; nice-looking tree. See the `tree-widget-image-enable', 110;; nice-looking tree. See the `tree-widget-image-enable',
@@ -133,19 +148,13 @@ The default is to use the \"tree-widget\" relative name."
133(defcustom tree-widget-theme nil 148(defcustom tree-widget-theme nil
134 "*Name of the theme where to look up for images. 149 "*Name of the theme where to look up for images.
135It must be a sub directory of the directory specified in variable 150It must be a sub directory of the directory specified in variable
136`tree-widget-themes-directory'. The default is \"default\". When an 151`tree-widget-themes-directory'. The default theme is \"default\".
137image is not found in this theme, the default theme is searched too. 152When an image is not found in a theme, it is searched in the default
138A complete theme must contain images with these file names with a 153theme.
139supported extension (see also `tree-widget-image-formats'): 154
155A complete theme must at least contain images with these file names
156with a supported extension (see also `tree-widget-image-formats'):
140 157
141\"open\"
142 Represent an expanded node.
143\"close\"
144 Represent a collapsed node.
145\"empty\"
146 Represent an expanded node with no child.
147\"leaf\"
148 Represent a leaf node.
149\"guide\" 158\"guide\"
150 A vertical guide line. 159 A vertical guide line.
151\"no-guide\" 160\"no-guide\"
@@ -153,9 +162,21 @@ supported extension (see also `tree-widget-image-formats'):
153\"end-guide\" 162\"end-guide\"
154 End of a vertical guide line. 163 End of a vertical guide line.
155\"handle\" 164\"handle\"
156 Horizontal guide line that joins the vertical guide line to a node. 165 Horizontal guide line that joins the vertical guide line to an icon.
157\"no-handle\" 166\"no-handle\"
158 An invisible handle." 167 An invisible handle.
168
169Plus images whose name is given by the :glyph-name property of the
170icon widgets used to draw the tree. By default these images are used:
171
172\"open\"
173 Icon associated to an expanded tree.
174\"close\"
175 Icon associated to a collapsed tree.
176\"empty\"
177 Icon associated to an expanded tree with no child.
178\"leaf\"
179 Icon associated to a leaf node."
159 :type '(choice (const :tag "Default" nil) 180 :type '(choice (const :tag "Default" nil)
160 (string :tag "Name")) 181 (string :tag "Name"))
161 :group 'tree-widget) 182 :group 'tree-widget)
@@ -171,6 +192,12 @@ supported extension (see also `tree-widget-image-formats'):
171 "*Default properties of XEmacs images." 192 "*Default properties of XEmacs images."
172 :type 'plist 193 :type 'plist
173 :group 'tree-widget) 194 :group 'tree-widget)
195
196(defcustom tree-widget-space-width 0.5
197 "Amount of space between an icon image and a node widget.
198Must be a valid space :width display property."
199 :group 'tree-widget
200 :type 'sexp)
174 201
175;;; Image support 202;;; Image support
176;; 203;;
@@ -297,6 +324,8 @@ properties. Typically it should contain something like this:
297 '(:ascent center :mask (heuristic t)) 324 '(:ascent center :mask (heuristic t))
298 )) 325 ))
299 326
327When there is no \"tree-widget-theme-setup\" library in the current
328theme directory, load the one from the default theme, if available.
300Default global properties are provided for respectively Emacs and 329Default global properties are provided for respectively Emacs and
301XEmacs in the variables `tree-widget-image-properties-emacs', and 330XEmacs in the variables `tree-widget-image-properties-emacs', and
302`tree-widget-image-properties-xemacs'." 331`tree-widget-image-properties-xemacs'."
@@ -308,12 +337,17 @@ XEmacs in the variables `tree-widget-image-properties-emacs', and
308 (file-name-directory file)) t t) 337 (file-name-directory file)) t t)
309 ;; If properties have been setup, use them. 338 ;; If properties have been setup, use them.
310 (unless (setq plist (aref tree-widget--theme 2)) 339 (unless (setq plist (aref tree-widget--theme 2))
311 ;; By default, use supplied global properties. 340 ;; Try from the default theme.
312 (setq plist (if (featurep 'xemacs) 341 (load (expand-file-name "../default/tree-widget-theme-setup"
313 tree-widget-image-properties-xemacs 342 (file-name-directory file)) t t)
314 tree-widget-image-properties-emacs)) 343 ;; If properties have been setup, use them.
315 ;; Setup the cache. 344 (unless (setq plist (aref tree-widget--theme 2))
316 (tree-widget-set-image-properties plist))) 345 ;; By default, use supplied global properties.
346 (setq plist (if (featurep 'xemacs)
347 tree-widget-image-properties-xemacs
348 tree-widget-image-properties-emacs))
349 ;; Setup the cache.
350 (tree-widget-set-image-properties plist))))
317 plist)) 351 plist))
318 352
319(defconst tree-widget--cursors 353(defconst tree-widget--cursors
@@ -321,10 +355,6 @@ XEmacs in the variables `tree-widget-image-properties-emacs', and
321 ;; This feature works since Emacs 22, and ignored on older versions, 355 ;; This feature works since Emacs 22, and ignored on older versions,
322 ;; and XEmacs. 356 ;; and XEmacs.
323 '( 357 '(
324 ("open" . hand )
325 ("close" . hand )
326 ("empty" . arrow)
327 ("leaf" . arrow)
328 ("guide" . arrow) 358 ("guide" . arrow)
329 ("no-guide" . arrow) 359 ("no-guide" . arrow)
330 ("end-guide" . arrow) 360 ("end-guide" . arrow)
@@ -357,7 +387,8 @@ found."
357 ;; Add the pointer shape 387 ;; Add the pointer shape
358 (cons :pointer 388 (cons :pointer
359 (cons 389 (cons
360 (cdr (assoc name tree-widget--cursors)) 390 (or (cdr (assoc name tree-widget--cursors))
391 'hand)
361 (tree-widget-image-properties file))))))))) 392 (tree-widget-image-properties file)))))))))
362 nil))))) 393 nil)))))
363 394
@@ -395,40 +426,39 @@ Return the image found, or nil if not found."
395 "Keymap used inside node buttons. 426 "Keymap used inside node buttons.
396Handle mouse button 1 click on buttons.") 427Handle mouse button 1 click on buttons.")
397 428
398(define-widget 'tree-widget-control 'push-button 429(define-widget 'tree-widget-icon 'push-button
399 "Basic widget other tree-widget node buttons are derived from." 430 "Basic widget other tree-widget icons are derived from."
400 :format "%[%t%]" 431 :format "%[%t%]"
401 :button-keymap tree-widget-button-keymap ; XEmacs 432 :button-keymap tree-widget-button-keymap ; XEmacs
402 :keymap tree-widget-button-keymap ; Emacs 433 :keymap tree-widget-button-keymap ; Emacs
434 :create 'tree-widget-icon-create
435 :action 'tree-widget-icon-action
436 :help-echo 'tree-widget-icon-help-echo
403 ) 437 )
404 438
405(define-widget 'tree-widget-open-control 'tree-widget-control 439(define-widget 'tree-widget-open-icon 'tree-widget-icon
406 "Button for an expanded tree-widget node." 440 "Icon for an expanded tree-widget node."
407 :tag "[-] " 441 :tag "[-]"
408 ;;:tag-glyph (tree-widget-find-image "open") 442 :glyph-name "open"
409 :notify 'tree-widget-close-node
410 :help-echo "Collapse node"
411 ) 443 )
412 444
413(define-widget 'tree-widget-empty-control 'tree-widget-open-control 445(define-widget 'tree-widget-empty-icon 'tree-widget-icon
414 "Button for an expanded tree-widget node with no child." 446 "Icon for an expanded tree-widget node with no child."
415 :tag "[X] " 447 :tag "[X]"
416 ;;:tag-glyph (tree-widget-find-image "empty") 448 :glyph-name "empty"
417 ) 449 )
418 450
419(define-widget 'tree-widget-close-control 'tree-widget-control 451(define-widget 'tree-widget-close-icon 'tree-widget-icon
420 "Button for a collapsed tree-widget node." 452 "Icon for a collapsed tree-widget node."
421 :tag "[+] " 453 :tag "[+]"
422 ;;:tag-glyph (tree-widget-find-image "close") 454 :glyph-name "close"
423 :notify 'tree-widget-open-node
424 :help-echo "Expand node"
425 ) 455 )
426 456
427(define-widget 'tree-widget-leaf-control 'item 457(define-widget 'tree-widget-leaf-icon 'tree-widget-icon
428 "Representation of a tree-widget leaf node." 458 "Icon for a tree-widget leaf node."
429 :tag " " ;; Need at least one char to display the image :-( 459 :tag ""
430 ;;:tag-glyph (tree-widget-find-image "leaf") 460 :glyph-name "leaf"
431 :format "%t" 461 :button-face 'default
432 ) 462 )
433 463
434(define-widget 'tree-widget-guide 'item 464(define-widget 'tree-widget-guide 'item
@@ -454,7 +484,7 @@ Handle mouse button 1 click on buttons.")
454 484
455(define-widget 'tree-widget-handle 'item 485(define-widget 'tree-widget-handle 'item
456 "Horizontal guide line that joins a vertical guide line to a node." 486 "Horizontal guide line that joins a vertical guide line to a node."
457 :tag " " 487 :tag "-"
458 ;;:tag-glyph (tree-widget-find-image "handle") 488 ;;:tag-glyph (tree-widget-find-image "handle")
459 :format "%t" 489 :format "%t"
460 ) 490 )
@@ -473,10 +503,12 @@ Handle mouse button 1 click on buttons.")
473 :value-get 'widget-value-value-get 503 :value-get 'widget-value-value-get
474 :value-delete 'widget-children-value-delete 504 :value-delete 'widget-children-value-delete
475 :value-create 'tree-widget-value-create 505 :value-create 'tree-widget-value-create
476 :open-control 'tree-widget-open-control 506 :action 'tree-widget-action
477 :close-control 'tree-widget-close-control 507 :help-echo 'tree-widget-help-echo
478 :empty-control 'tree-widget-empty-control 508 :open-icon 'tree-widget-open-icon
479 :leaf-control 'tree-widget-leaf-control 509 :close-icon 'tree-widget-close-icon
510 :empty-icon 'tree-widget-empty-icon
511 :leaf-icon 'tree-widget-leaf-icon
480 :guide 'tree-widget-guide 512 :guide 'tree-widget-guide
481 :end-guide 'tree-widget-end-guide 513 :end-guide 'tree-widget-end-guide
482 :no-guide 'tree-widget-no-guide 514 :no-guide 'tree-widget-no-guide
@@ -553,32 +585,35 @@ WIDGET's :node sub-widget."
553 (widget-put arg :value (widget-value child)) 585 (widget-put arg :value (widget-value child))
554 ;; Save properties specified in :keep. 586 ;; Save properties specified in :keep.
555 (tree-widget-keep arg child))))) 587 (tree-widget-keep arg child)))))
556 588
557(defvar tree-widget-after-toggle-functions nil 589;;; Widget creation
558 "Hooks run after toggling a tree-widget expansion. 590;;
559Each function will receive the tree-widget as its unique argument. 591(defvar tree-widget-before-create-icon-functions nil
560This hook should be local in the buffer used to display widgets.") 592 "Hooks run before to create a tree-widget icon.
561 593Each function is passed the icon widget not yet created.
562(defun tree-widget-close-node (widget &rest ignore) 594The value of the icon widget :node property is a tree :node widget or
563 "Collapse the tree-widget, parent of WIDGET. 595a leaf node widget, not yet created.
564WIDGET is, or derives from, a tree-widget-open-control widget. 596This hook can be used to dynamically change properties of the icon and
565IGNORE other arguments." 597associated node widgets. For example, to dynamically change the look
566 (let ((tree (widget-get widget :parent))) 598and feel of the tree-widget by changing the values of the :tag
567 ;; Before to collapse the node, save children values so next open 599and :glyph-name properties of the icon widget.
568 ;; can recover them. 600This hook should be local in the buffer setup to display widgets.")
569 (tree-widget-children-value-save tree) 601
570 (widget-put tree :open nil) 602(defun tree-widget-icon-create (icon)
571 (widget-value-set tree nil) 603 "Create the ICON widget."
572 (run-hook-with-args 'tree-widget-after-toggle-functions tree))) 604 (run-hook-with-args 'tree-widget-before-create-icon-functions icon)
573 605 (widget-put icon :tag-glyph
574(defun tree-widget-open-node (widget &rest ignore) 606 (tree-widget-find-image (widget-get icon :glyph-name)))
575 "Expand the tree-widget, parent of WIDGET. 607 ;; Ensure there is at least one char to display the image.
576WIDGET is, or derives from, a tree-widget-close-control widget. 608 (and (widget-get icon :tag-glyph)
577IGNORE other arguments." 609 (equal "" (or (widget-get icon :tag) ""))
578 (let ((tree (widget-get widget :parent))) 610 (widget-put icon :tag " "))
579 (widget-put tree :open t) 611 (widget-default-create icon)
580 (widget-value-set tree t) 612 ;; Insert space between the icon and the node widget.
581 (run-hook-with-args 'tree-widget-after-toggle-functions tree))) 613 (insert-char ? 1)
614 (put-text-property
615 (1- (point)) (point)
616 'display (list 'space :width tree-widget-space-width)))
582 617
583(defun tree-widget-value-create (tree) 618(defun tree-widget-value-create (tree)
584 "Create the TREE tree-widget." 619 "Create the TREE tree-widget."
@@ -598,37 +633,34 @@ IGNORE other arguments."
598 (let ((args (widget-get tree :args)) 633 (let ((args (widget-get tree :args))
599 (xpandr (or (widget-get tree :expander) 634 (xpandr (or (widget-get tree :expander)
600 (widget-get tree :dynargs))) 635 (widget-get tree :dynargs)))
601 (leaf (widget-get tree :leaf-control))
602 (guide (widget-get tree :guide)) 636 (guide (widget-get tree :guide))
603 (noguide (widget-get tree :no-guide)) 637 (noguide (widget-get tree :no-guide))
604 (endguide (widget-get tree :end-guide)) 638 (endguide (widget-get tree :end-guide))
605 (handle (widget-get tree :handle)) 639 (handle (widget-get tree :handle))
606 (nohandle (widget-get tree :no-handle)) 640 (nohandle (widget-get tree :no-handle))
607 (leafi (tree-widget-find-image "leaf"))
608 (guidi (tree-widget-find-image "guide")) 641 (guidi (tree-widget-find-image "guide"))
609 (noguidi (tree-widget-find-image "no-guide")) 642 (noguidi (tree-widget-find-image "no-guide"))
610 (endguidi (tree-widget-find-image "end-guide")) 643 (endguidi (tree-widget-find-image "end-guide"))
611 (handli (tree-widget-find-image "handle")) 644 (handli (tree-widget-find-image "handle"))
612 (nohandli (tree-widget-find-image "no-handle")) 645 (nohandli (tree-widget-find-image "no-handle")))
613 child)
614 ;; Request children at run time, when not already done. 646 ;; Request children at run time, when not already done.
615 (when (and (not args) xpandr) 647 (when (and (not args) xpandr)
616 (setq args (mapcar 'widget-convert (funcall xpandr tree))) 648 (setq args (mapcar 'widget-convert (funcall xpandr tree)))
617 (widget-put tree :args args)) 649 (widget-put tree :args args))
618 ;; Insert the node "open" button. 650 ;; Create the icon widget for the expanded tree.
619 (push (widget-create-child-and-convert 651 (push (widget-create-child-and-convert
620 tree (widget-get 652 tree (widget-get tree (if args :open-icon :empty-icon))
621 tree (if args :open-control :empty-control)) 653 ;; At this point the node widget isn't yet created.
622 :tag-glyph (tree-widget-find-image 654 :node (setq node (widget-convert node)))
623 (if args "open" "empty")))
624 buttons) 655 buttons)
625 ;; Insert the :node element. 656 ;; Create the tree node widget.
626 (push (widget-create-child-and-convert tree node) 657 (push (widget-create-child tree node) children)
627 children) 658 ;; Update the icon :node with the created node widget.
628 ;; Insert children. 659 (widget-put (car buttons) :node (car children))
660 ;; Create the tree children.
629 (while args 661 (while args
630 (setq child (car args) 662 (setq node (car args)
631 args (cdr args)) 663 args (cdr args))
632 (and indent (insert-char ?\ indent)) 664 (and indent (insert-char ?\ indent))
633 ;; Insert guide lines elements from previous levels. 665 ;; Insert guide lines elements from previous levels.
634 (dolist (f (reverse flags)) 666 (dolist (f (reverse flags))
@@ -644,30 +676,92 @@ IGNORE other arguments."
644 ;; Insert the node handle line 676 ;; Insert the node handle line
645 (widget-create-child-and-convert 677 (widget-create-child-and-convert
646 tree handle :tag-glyph handli) 678 tree handle :tag-glyph handli)
647 ;; If leaf node, insert a leaf node button. 679 (if (tree-widget-p node)
648 (unless (tree-widget-p child) 680 ;; Create a sub-tree node.
681 (push (widget-create-child-and-convert
682 tree node :tree-widget--guide-flags
683 (cons (if args t) flags))
684 children)
685 ;; Create the icon widget for a leaf node.
649 (push (widget-create-child-and-convert 686 (push (widget-create-child-and-convert
650 tree leaf :tag-glyph leafi) 687 tree (widget-get tree :leaf-icon)
651 buttons)) 688 ;; At this point the node widget isn't yet created.
652 ;; Finally, insert the child widget. 689 :node (setq node (widget-convert
653 (push (widget-create-child-and-convert 690 node :tree-widget--guide-flags
654 tree child 691 (cons (if args t) flags)))
655 :tree-widget--guide-flags (cons (if args t) flags)) 692 :tree-widget--leaf-flag t)
656 children))) 693 buttons)
694 ;; Create the leaf node widget.
695 (push (widget-create-child tree node) children)
696 ;; Update the icon :node with the created node widget.
697 (widget-put (car buttons) :node (car children)))))
657;;;; Collapsed node. 698;;;; Collapsed node.
658 ;; Insert the "closed" node button. 699 ;; Create the icon widget for the collapsed tree.
659 (push (widget-create-child-and-convert 700 (push (widget-create-child-and-convert
660 tree (widget-get tree :close-control) 701 tree (widget-get tree :close-icon)
661 :tag-glyph (tree-widget-find-image "close")) 702 ;; At this point the node widget isn't yet created.
703 :node (setq node (widget-convert node)))
662 buttons) 704 buttons)
663 ;; Insert the :node element. 705 ;; Create the tree node widget.
664 (push (widget-create-child-and-convert tree node) 706 (push (widget-create-child tree node) children)
665 children)) 707 ;; Update the icon :node with the created node widget.
666 ;; Save widget children and buttons. The :node child is the first 708 (widget-put (car buttons) :node (car children)))
667 ;; element in children. 709 ;; Save widget children and buttons. The tree-widget :node child
710 ;; is the first element in :children.
668 (widget-put tree :children (nreverse children)) 711 (widget-put tree :children (nreverse children))
669 (widget-put tree :buttons buttons) 712 (widget-put tree :buttons buttons)))
670 )) 713
714;;; Widget callbacks
715;;
716(defsubst tree-widget-leaf-node-icon-p (icon)
717 "Return non-nil if ICON is a leaf node icon.
718That is, if its :node property value is a leaf node widget."
719 (widget-get icon :tree-widget--leaf-flag))
720
721(defun tree-widget-icon-action (icon &optional event)
722 "Handle the ICON widget :action.
723If ICON :node is a leaf node it handles the :action. The tree-widget
724parent of ICON handles the :action otherwise.
725Pass the received EVENT to :action."
726 (let ((node (widget-get icon (if (tree-widget-leaf-node-icon-p icon)
727 :node :parent))))
728 (widget-apply node :action event)))
729
730(defun tree-widget-icon-help-echo (icon)
731 "Return the help-echo string of ICON.
732If ICON :node is a leaf node it handles the :help-echo. The tree-widget
733parent of ICON handles the :help-echo otherwise."
734 (let* ((node (widget-get icon (if (tree-widget-leaf-node-icon-p icon)
735 :node :parent)))
736 (help-echo (widget-get node :help-echo)))
737 (if (functionp help-echo)
738 (funcall help-echo node)
739 help-echo)))
740
741(defvar tree-widget-after-toggle-functions nil
742 "Hooks run after toggling a tree-widget expansion.
743Each function is passed a tree-widget. If the value of the :open
744property is non-nil the tree has been expanded, else collapsed.
745This hook should be local in the buffer setup to display widgets.")
746
747(defun tree-widget-action (tree &optional event)
748 "Handle the :action of the TREE tree-widget.
749That is, toggle expansion of the TREE tree-widget.
750Ignore the EVENT argument."
751 (let ((open (not (widget-get tree :open))))
752 (or open
753 ;; Before to collapse the node, save children values so next
754 ;; open can recover them.
755 (tree-widget-children-value-save tree))
756 (widget-put tree :open open)
757 (widget-value-set tree open)
758 (run-hook-with-args 'tree-widget-after-toggle-functions tree)))
759
760(defun tree-widget-help-echo (tree)
761 "Return the help-echo string of the TREE tree-widget."
762 (if (widget-get tree :open)
763 "Collapse node"
764 "Expand node"))
671 765
672(provide 'tree-widget) 766(provide 'tree-widget)
673 767