* Kenny Tilton 48DFA037.3030705@optonline.net : Wrote on Sun, 28 Sep 2008 11:18:15 -0400: |> The issue was that I could not figure out how to limit expansions down |> the tree using a kids rule at make-instance time. | | That was what I was trying to suggest with the above excerpt, but I | was too terse: just have the kids rule first check another cell, the | openp slot. When that goes to t the kids will be generated, when it | goes to nil they can go away. If you think you need to avoid | recreating the clos instances you are probably wrong, but you can just | make the container collapsed when not openp (and play any number of | tricks to avoid the rule rerunning when openp goes to nil and tossing | all the kids.
openp is a slot on treeview-item that controls the ".pathname item -open node" tcl command. I'm using `openedp' for a new variable.
| ie, This is a very common requirement solved without SETF. But I | commend your creativity in finding a solution, and the extensive work | you did wiring in treeview. You are a quick study! | | |> The general idea was |> directories should be expanded only when needed. [Further I was using |> `expandedp' to ensure that directories got expanded only once, even if |> they were opened multiple times by on-open events]. I couldn't combine |> these requirements with the desired initial state. | | No, you forgot to ask me how. But I understand, I usually charge ahead | on my own too and Just Get It Working.
You know what? Youre right. I'm appending the code to this message, it is a bit simpler without those :after methods on make-tk-instance.
There is still a question -- of triggering a (setf (^openp) t) in a dirtree-node kids rule.
|> Besides, this was supposed to demo the idea that the tree represented in |> the family's hierarchical model is directly displayed by the widget. So |> manipulating the model (adding kids, sorting the kids) should reflect in |> the displayed tree. | | ? How does this mandate abandonment of the declarative paradigm?
The declarative paradigm is already there, to be chosen and used. All that is being done is support is also added for a traditional container-contains hierarchy, so one can reach for it JUST IN CASE one needs it. -- Madhu
PS: Here is the code, in full declarative glory :)
(defun dirtree-make-kids (self) (loop for p in (dirtree-expand (etypecase self (dirtree-node (my-pathname self)) (dirtree #p"/"))) collect (make-kid 'dirtree-node :my-pathname p)))
(defmd dirtree-node (treeview-item) my-pathname (openp (c-in nil)) (openedp (c-in nil)) (directoryp (c? (bwhen (p (^my-pathname)) (dirtree-directory-p p)))) :text (c? (bwhen (p (^my-pathname)) (if (^directoryp) (concatenate 'string (car (last (cdr (pathname-directory p)))) "/") (file-namestring p)))) :values-lst (c? (bwhen (p (^my-pathname)) (list (namestring p) (or (ignore-errors (with-open-file (stream p) (file-length stream))) "") (or (bwhen (utime (file-write-date p)) (dirtree-format-date utime)) "")))) :on-open (lambda (self) (setf (^openedp) t)) :on-close (lambda (self) (setf (^openedp) nil)) :kids (c? (the-kids (if (^openedp) (dirtree-make-kids self) (when (^directoryp) (make-kid 'dirtree-node :text "dummy"))))))
(defmd dirtree (treeview) :column-ids '("ABSOLUTE-PATHNAME" "SIZE" "DATE") :displaycolumns '("SIZE" "DATE") :kids (c? (the-kids (make-kid 'dirtree-node :my-pathname #p"/" :text "/"))) :treeview-headings (c? (the-kids (mk-treeview-heading :treeview-column-id "#0" :text "Directory Structure") (mk-treeview-heading :treeview-column-id "SIZE" :text "File Size") (mk-treeview-heading :treeview-column-id "DATE" :text "Write date (utime)"))))