Madhu wrote:
- Kenny Tilton 48DEA802.1050303@optonline.net :
Wrote on Sat, 27 Sep 2008 17:39:14 -0400:
| Can't you just have: | | :on-open (lambda (self) (setf (openp self) t)) | | And have a kids rule: | (c? (when (^openp)...)) | | From the code it looks like you understand this. Maybe you ran into an | issue?
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.
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.
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?
Anyway I figured out how to initalize kids the way I wanted: Don't do it in the defmodel form (you cant get hold of a parent object there),
Yes you can, but only if you use rules for the kids slot. The trick is always to /grow/ a Family tree with rules on the kids slot.
just do it in make-tk-instance. FWIW I'm attaching the current version. There may be an outstanding bug around openp.
BTW, there is a problem with tk-format: if youre passing strings with ~, FORMAT will barf on strange directives. Dirty workaround:
(defmethod tk-send-value :around ((s string)) (sanitize-string-for-format (call-next-method)))
(defun sanitize-string-for-format (string) (let ((n (count #~ string))) (if (zerop n) string (let ((ret (make-string (+ n (length string)) :element-type (type-of (char string 0)))) (i -1)) (loop for c across string do (setf (aref ret (incf i)) c) if (eql c #~) do (setf (aref ret (incf i)) c)) ret))))
Thx!
kt