PDA

View Full Version : create graphical browser tree dinamically


lcsoft
11-19-2004, 08:18 AM
Hi all!

I'm trying to create a graphical browser tree dinamically.

i.e. I want to define the nodes via reading a file or so on.

A first attempt is to eval a string that contains the code that creats a node (so I can put this code in a loop).

So (code from the gbrowser example in the OSDM docs):

[CUT]

(setq a1 (sd-create-browsernode :tree "lisp-tree" :parent root
:objPath "/AA1" :objPname "aa1" :objClientData
(make-interrogator)))

(setq num '5)

;;make five children
(setq foo '(dotimes (x num) (sd-create-browsernode :tree "lisp-tree" :parent a1
:objPname (format nil "test~A" x) :objClientData
(make-interrogator :enum-type "PART") )))

(eval foo)

[CUT]

In this example there are 2 variables: a1 and num.

But the error I get is:

LISP error:
"The variable A1 is unbound. This may have been caused by:
(1) Entering a string that wasn't enclosed in quotes.
(2) Entering a command belonging to a module that has not been activated.
(3) Trying to load a file that has an incorrect format.
(4) Calling a function that has not been enclosed in parenthesis ()."

after a lot of experiments, I still do not understand this error (experiments with only the variable num are correct).

Can you give me an answer?

Thanks in advance.

clausb
11-19-2004, 08:50 AM
I would guess this is a LISP package problem (a1 defined in one package, but used from another).

But I don't really understand why you are using all those quotes and the 'eval' command in the code.

(setq foo '(some-command some-parameter))
(eval foo)

... should be equivalent to ...

(some-command some-parameter)

The second version is of course a lot simpler and easier to debug, so that would always be my preference. What am I missing?

Claus

lcsoft
11-19-2004, 02:06 PM
Thanks for the answer!

Originally posted by clausb
I would guess this is a LISP package problem (a1 defined in one package, but used from another).


No, there is simply one file where is the code of the gbrowser demo from the docs.


But I don't really understand why you are using all those quotes and the 'eval' command in the code.


I'd like to read a text file and to define, with a loop on the file lines, n variables.
So I read a single line of the file and I create a string with the declaration (a1 at the first line, an at the nth line) and eval it to obtain the declarations needed by the gbrowser widget.

clausb
11-19-2004, 02:13 PM
Could you post the complete file so that I could have a look? (Still don't understand why you're going the 'eval' route.)

Thanks,

Claus

lcsoft
11-19-2004, 04:23 PM
Originally posted by clausb
Could you post the complete file so that I could have a look? (Still don't understand why you're going the 'eval' route.)


Thanks!

The code is long (11k) but it's the example of a gbrowser implementation that you cand find in the examples of OSDM.

The piece of code that I want to make dynamic is the part where the nodes are defined:



(defun test-tree()
;;test function to build a tree
(let (root a2 a4 a1 p1 p3 p4 p5 a3)
(setq root (sd-create-browsernode :tree "lisp-tree" :parent nil
:objClientData (make-interrogator :drag-source nil)))
(setq a2 (sd-create-browsernode :tree "lisp-tree" :parent root
:objPname "A2" :objClientData
(make-interrogator :display-name "No Drag Source"
:drag-source nil :enum-type "ASSEMBLY")))
(setq a4 (sd-create-browsernode :tree "lisp-tree" :parent root
:objPath "/A4" :objPname "a4" :objClientData
(make-interrogator :is-sensitive nil
:is-expandable nil)))
(setq a1 (sd-create-browsernode :tree "lisp-tree" :parent root
:objPath "/A1" :objPname "a1" :objClientData
(make-interrogator)))

;;make five children
(dotimes (x 5)
(sd-create-browsernode :tree "lisp-tree" :parent a1
:objPname (format nil "test~A" x) :objClientData
(make-interrogator :enum-type "PART")))

(setq p1 (sd-create-browsernode :tree "lisp-tree" :parent root
:objPath "/P1" :objPname "p1" :objClientData
(make-interrogator :display-in-graphics nil
:is-expandable nil
:primary-pixmap "GB Test Unpinned"
:enum-type "FEATURE")))
(setq a3 (sd-create-browsernode :tree "lisp-tree" :parent a2
;:objPath "/A2/A3"
:objPname "a3" :objClientData
(make-interrogator :enum-type "ASSEMBLY")))
(setq p4 (sd-create-browsernode :tree "lisp-tree" :parent a1
:objPath "/A1/P4" :objPname "p4" :objClientData
(make-interrogator :is-selectable nil
:display-name "Non Selectable"
:is-expandable nil
:enum-type "REL-SET")))
(setq p3 (sd-create-browsernode :tree "lisp-tree" :parent a1
:objPath "/A1/P3" :objPname "p3" :objClientData
(make-interrogator :display-in-graphics nil
:is-expandable nil
:primary-pixmap "GB Test Unpinned")))
(setq p5 (sd-create-browsernode :tree "lisp-tree" :parent a3
:objPath "/A2/A3/P5" :objPname "p5" :objClientData
(make-interrogator :display-in-graphics t
:is-expandable nil
:drag-target nil
:primary-pixmap "GB Test Unpinned"
:display-name "No Target")))
)
)



here the nodes are hardcoded. I'd like to make the definitions of tree not hardcoded but "file-dependent".

clausb
11-19-2004, 10:53 PM
If you want to build a dynamic structure, the usual solution is to use dynamic datastructures (instead of a set of hard-coded and predefined variables). For instance, you could read your text file and build up a tree structure from it. That is what you hold in memory. Whenever it is time to (re)build the browser (see the gbrowser documentation in the Integration Kit for details), you simply recurse over your model tree and call sd-create-browsernode for each node in your tree. That's it.

Alternatively, you could also re-read the data every time from the file, which would eliminate the intermediate model tree in memory. That's probably too slow for most practical purposes. There are probably also intermediate solutions.

I've added a simple (actually, simplistic) file system directory browser example to my macro collection on my web site at http://www.clausbrod.de/Osdm/OsdmMacros which will hopefully be inspiring. You'll find that even though the tree is built up from dynamic data, I did not have to use 'eval'.

HTH,

Claus