PDA

View Full Version : Popup_list to Popup_list Control



dhurd
2005-01-10, 05:26 PM
I would like to have the user input from the first popup list control the available selections in the second list ie.
popup1LIST: FRUIT, COLORS, CARS
popup2LISTa: APPLES, ORANGES, PEARS
popup2LISTb: RED, GREEN, BLUE
popup2LISTc: VW, CHEVY, FORD

I only want the selections of list "b" if the user picks "COLORS",etc.

I've tried different types of "if" statements in the action_tile reaction area to no avail.

stig.madsen
2005-01-10, 07:38 PM
There are various techniques you can use. Guess the preferred method depends on which form you get the data and the kind of operations you need to perform.

Unless other constructs are needed, I like to keep all the data in one place. For example, the data you describe could be gathered in a single list looking like this:

(("FRUIT" ("APPLES" "ORANGES" "PEARS"))
("COLORS" ("RED" "GREEN" "BLUE"))
("CARS" ("VW" "CHEVY" "FORD")))

When using the dcl list functions, one would simply add the CAR items to the popup_list and specify a callback that populates the list_box with whatever of the CAR items is chosen in the popup.

For example:


// DCL definition

myTest : dialog {
label = "Test list controls";
: list_box {
key = "listbox";
width = 20;
}
: popup_list {
key = "popup";
width = 20;
}
ok_only;
}

;; LISP code

(defun populate_list (tile item lst)
(start_list tile)
(mapcar 'add_list (cadr (nth item lst)))
(end_list)
)

(defun listtest ()
;; set up data
(setq myList '(("FRUIT" ("APPLES" "ORANGES" "PEARS"))
("COLORS" ("RED" "GREEN" "BLUE"))
("CARS" ("VW" "CHEVY" "FORD"))
)
)

(setq dcl_id (load_dialog "testdlg.dcl"))
(cond ((new_dialog "myTest" dcl_id)

;; fill "popup" with CAR item of myList
(start_list "popup")
(mapcar 'add_list (mapcar 'car myList))
(end_list)

;; fill "listbox" initially, according to default value of "popup"
;; (value of "0" unless otherwise specified in the dcl definition)
(populate_list "listbox" 0 myList)

;; define callback to populate "listbox" according to
;; users choice in the "popup" tile
(action_tile "popup" "(populate_list \"listbox\" (atoi $value) myList)")

(start_dialog)
)
)
)

You will probably need to keep track of the chosen item(s) in the list_box. This could for be done by having the populate_list function return the sublist data plus setting the chosen item during callback from the list_box. Here's a simple example where the single choice is saved and returned (for single-selection list_box):



// DCL definition

myTest : dialog {
label = "Test list controls";
: list_box {
key = "listbox";
width = 20;
}
: popup_list {
key = "popup";
width = 20;
}
: edit_box {
key = "editbox";
width = 20;
}
ok_only;
}


;; LISP code

(defun populate_list (tile item lst cleartiles / sublst)
(start_list tile)
(mapcar 'add_list (setq sublst (cadr (nth item lst))))
(end_list)

;; clear any affected tiles
(foreach n cleartiles
(set_tile n "")
)
;; return sublist
sublst
)

(defun listtest ()
;; set up data
(setq myList '(("FRUIT" ("APPLES" "ORANGES" "PEARS"))
("COLORS" ("RED" "GREEN" "BLUE"))
("CARS" ("VW" "CHEVY" "FORD"))
)
)

(setq dcl_id (load_dialog "testdlg.dcl"))
(cond ((new_dialog "myTest" dcl_id)
(setq item "")

;; fill "popup" with CAR item of myList
(start_list "popup")
(mapcar 'add_list (mapcar 'car myList))
(end_list)

;; fill "listbox" according to default value of "popup" (value
;; of zero unless otherwise specified in the dcl definition)
(setq subitems (populate_list "listbox" 0 myList '("editbox")))

;; define callback to populate "listbox" according to
;; users choice in the "popup" tile. Save list of items
;; in order to extract an item from the list_box tile
;; (also clear any choices in affected tiles when replacing list)
(action_tile "popup" "(setq subitems (populate_list \"listbox\" (atoi $value) myList '(\"editbox\")))")

;; define callback to populate "editbox" and save current
;; choice in order to return it
(action_tile "listbox" "(set_tile \"editbox\" (setq item (nth (atoi $value) subitems)))")

(start_dialog)

;; report choice, if any
(princ (strcat "You chose " (if (/= item "") item "nothing")))
)
)
(princ)
)

dhurd
2005-02-07, 07:36 PM
Stig,

Thanks for the help. I'm not sure if I want to persue the route you've listed as the depth of the list tree gets too complicated at the nth (about 8) level. Your base code works well though and I'll most likely use it in annother app.

TY
Dave

CAB2k
2005-02-08, 07:07 PM
I don't see that it gets too complicated?
Although you may want to restructure the list so they can be more dynamic & not redundant,

(setq Level1 (list
'("REDFRUIT" 0) ; 0 points to element in next level
'("COLORS" 1)
'("CARS" 2)
'("FRAGRANCE" 0) ; reuse a list
)
)
(setq Level2 (list
(list
'("APPLES" 0)
'("ORANGES" 1)
'("PEARS" 2)
)
(list
'("RED" 0)
'("GREEN" 1)
'("BLUE" 2)
)
(list
'("VW" 0)
'("CHEVY" 1)
'("FORD" 2)
)
)
)
;; levels could continue.
;; another pointer scheme could be ("APPLES" level3 0)
;; where 'level3' holds the list and 0 is the pointer

bizello
2008-09-12, 02:22 PM
Hi,

How do the same if I want get data from txt files. This is easier to change data without rewrite LISP and DCL code.

Thank you

Sérgio

cadking2k5683822
2018-04-20, 09:08 PM
What if I want each color in a different list box and just the size of the text