The AutoLisp Tutorial - DCL

Dialog Control Language - Part 3


  Part 3 - List_Box  


   Let's build a working DCL file showing us exactly how to handle list boxes.

 We will build a DCL file containing two list boxes plus an Okay and Cancel button.  We will set the first list box to single selection and the second to multiple selection.  The selected items will be displayed on the screen after the user presses the Okay button.


  Layout thoughts:   I will place the list boxes in a row, (side by side).  Then I'll put the Okay and Cancel buttons in a row at the bottom of the dialog box.  So...I'll need something like this:

: column {
  : boxed_row {
    : list_box {
      // Put code for list_box 1 here
    } 
    : list_box { 
      // Put code for list_box 2 here 
    } 
  } 
  : boxed_row {
    : button {

       // Put code for the Okay button here
    } 
    : button {

       // Put code for the Cancel button here
    }
  }  
}


Let's copy in the code for the header and all of the controls above from the "Controls" section of this tutorial.  I'll show them in red.  Notice the key names and labels had to be changed.

SAMPLE3 : dialog {
          label = "Sample Dialog Box Routine - Part 3";

          : column {
            : boxed_row {
              : list_box {
                label ="Choose Item";
                key = "mylist1";
                height = 15;
                width = 25;
                multiple_select = false;
                fixed_width_font = true;
                value = "";
              }
              : list_box {
                label ="Choose Items";
                key = "mylist2";
                height = 15;
                width = 25;
                multiple_select = true;
                fixed_width_font = true;
                value = "";
              }
            }
            : boxed_row {
              : button {
                key = "accept";
                label = " Okay ";
                is_default = true;

              }
              : button {
                key = "cancel";
                label = " Cancel ";
                is_default = false;
                is_cancel = true;

              }
            }
          }

}

Right click and copy the above. Open NotePad and paste it.  Save the file as SAMPLE3.DCL  Be sure to change the "Save as Type" drop down box to "All Files" before saving it or it will put a  ".txt" extension on the file name.  Save this file somewhere in the AutoCAD search path.


  Next we will get a copy of the AutoLisp model and revise it.  All new code is shown in red.

(defun C:SAMPLE3()

  ;;;--- Load the dcl file
  (setq dcl_id (load_dialog "SAMPLE3.dcl"))

  ;;;--- Load the dialog definition if it is not already loaded
  (if (not (new_dialog "SAMPLE3" dcl_id) ) (exit))

  ;;;--- If an action event occurs, do this function
  (action_tile "accept" "(setq ddiag 2)(saveVars)(done_dialog)")
  (action_tile "cancel" "(setq ddiag 1)(done_dialog)")

  ;;;--- Display the dialog box
  (start_dialog)

  ;;;--- Unload the dialog box
  (unload_dialog dcl_id)

  ;;;--- If the user pressed the Cancel button
  (if(= ddiag 1)
    (princ "\n Sample3 cancelled!")
  )

  ;;;--- If the user pressed the Okay button
  (if(= ddiag 2)
    (progn
      (princ "\n The user pressed Okay!")
    )
  )

  ;;;--- Suppress the last echo for a clean exit
  (princ)

)
 

  Right click and copy the above. Open NotePad and paste it.  Save the file as SAMPLE3.LSP  Be sure to change the "Save as Type" drop down box to "All Files" before saving it or it will put a  ".txt" extension on the file name.  Save this file somewhere in the AutoCAD search path.


  Let's load the program and see what the DCL file looks like.  On the command line type this:

Command: (load "sample3") and press enter

  You should see this

C:Sample3
Command:

  Now type Sample3 and press enter.  If everything went according to plan you should see this on your screen:

 

DCL_PART301.jpg (17524 bytes)


   Looks good but, there is nothing to choose.  Let's add some data to the list boxes.  We will need two list.  We will call the list for the first list box myList1 and the second myList2.

  (setq myList1(list "Electrical" "Structural" "Plumbing" "Foundation"))

  (setq myList2(list "Plastic" "Steel" "Aluminum" "Concrete"))

Alrighty then, we have our list built.  All we have to do is put them in the dialog box. We will use the start_list, add_list, and end_list functions.  Start_list tells DCL which list_box we are going to edit.  The identification is made by using the list_box KEY.  The first list has a key of "mylist1" and the second has a key of "mylist2".  So the start_list function would look like this:

(start_list "mylist1" 3)   ; The 3 means we want to delete the old contents and start new.

  Next we use the add_list function to tell DCL which list to put in the list_box.   We use the mapcar function to apply add_list to each member in the list.  Our list for the first list_box is named myList1.  So...

(mapcar 'add_list myList1)

  Finally we use the end_list function to tell DCL to display the new contents because we are through editing the list. 

(end_list)

To look at it all together:

(start_list "mylist1" 3)
(mapcar 'add_list myList1)
(end_list)

(start_list "mylist2" 3)
(mapcar 'add_list myList2)
(end_list)

 

  Let's add all of this to the AutoLisp program and see what it looks like.

(defun C:SAMPLE3()

  (setq myList1(list "Electrical" "Structural" "Plumbing" "Foundation"))
  (setq myList2(list "Plastic" "Steel" "Aluminum" "Concrete"))

  ;;;--- Load the dcl file
  (setq dcl_id (load_dialog "SAMPLE3.dcl"))

  ;;;--- Load the dialog definition if it is not already loaded
  (if (not (new_dialog "SAMPLE3" dcl_id) ) (exit))

  (start_list "mylist1" 3)
  (mapcar 'add_list myList1)
  (end_list)

  (start_list "mylist2" 3)
  (mapcar 'add_list myList2)
  (end_list)

  ;;;--- If an action event occurs, do this function
  (action_tile "accept" "(setq ddiag 2)(saveVars)(done_dialog)")
  (action_tile "cancel" "(setq ddiag 1)(done_dialog)")

  ;;;--- Display the dialog box
  (start_dialog)

  ;;;--- Unload the dialog box
  (unload_dialog dcl_id)

  ;;;--- If the user pressed the Cancel button
  (if(= ddiag 1)
    (princ "\n Sample3 cancelled!")
  )

  ;;;--- If the user pressed the Okay button
  (if(= ddiag 2)
    (progn
      (princ "\n The user pressed Okay!")
    )
  )

  ;;;--- Suppress the last echo for a clean exit
  (princ)

)
 

  Notice the location of the red lines.  We create the list before loading the dialog box.  We add the list to the dialog box after it is loaded with new_dialog and before the action_tile statements.  This is the order you should use. 


   Looking good so far.  We need to add the SaveVars function to save the selected items from the list boxes when the Okay button is pressed.  Look at the blue text in the Sample3.lsp program above.

  Let's steal the saveVars routine from the list_box control on the "List and how to handle them" page of this tutorial and modify it.  I'll show the modifications in red.

 

(defun saveVars(/ readlist count item)

  ;;;--- Setup a list to hold the selected items
  (setq retList(list))

  ;;;--- Save the list setting
  (setq readlist(get_tile "mylist1"))

  ;;;--- Setup a variable to run through the list
  (setq count 1)

  ;;;--- cycle through the list getting all of the selected items
  (while (setq item (read readlist))
    (setq retlist(append retList (list (nth item myList1))))
    (while
      (and
        (/= " " (substr readlist count 1))
        (/= ""   (substr readlist count 1))
      )
      (setq count (1+ count))
    )
    (setq readlist (substr readlist count))
  )
)

  Wow! That was easy.  Wait a minute, we have two list boxes.  We will have to create a function out of this or simply copy this and do it twice.  For now, let's just do it twice.


Our program would now look like this:

(defun saveVars(/ readlist count item)

  ;;;--- Setup a list to hold the selected items
  (setq retList(list))

  ;;;--- Save the list setting
  (setq readlist(get_tile "mylist1"))

  ;;;--- Setup a variable to run through the list
  (setq count 1)

  ;;;--- cycle through the list getting all of the selected items
  (while (setq item (read readlist))
    (setq retlist(append retList (list (nth item myList1))))
    (while
      (and
        (/= " " (substr readlist count 1))
        (/= ""   (substr readlist count 1))
      )
      (setq count (1+ count))
    )
    (setq readlist (substr readlist count))
  )

  ;;;--- Setup a list to hold the selected items
  (setq retList2(list))

  ;;;--- Save the list setting
  (setq readlist(get_tile "mylist2"))

  ;;;--- Setup a variable to run through the list
  (setq count 1)

  ;;;--- cycle through the list getting all of the selected items
  (while (setq item (read readlist))
    (setq retlist2(append retList2 (list (nth item myList2))))
    (while
      (and
        (/= " " (substr readlist count 1))
        (/= ""   (substr readlist count 1))
      )
      (setq count (1+ count))
    )
    (setq readlist (substr readlist count))
  )
)

 

(defun C:SAMPLE3()

  (setq myList1(list "Electrical" "Structural" "Plumbing" "Foundation"))
    (setq myList2(list "Plastic" "Steel" "Aluminum" "Concrete"))

  ;;;--- Load the dcl file
  (setq dcl_id (load_dialog "SAMPLE3.dcl"))

  ;;;--- Load the dialog definition if it is not already loaded
  (if (not (new_dialog "SAMPLE3" dcl_id) ) (exit))

  (start_list "mylist1" 3)
  (mapcar 'add_list myList1)
  (end_list)

  (start_list "mylist2" 3)
  (mapcar 'add_list myList2)
  (end_list)

  ;;;--- If an action event occurs, do this function
  (action_tile "accept" "(setq ddiag 2)(saveVars)(done_dialog)")
  (action_tile "cancel" "(setq ddiag 1)(done_dialog)")

  ;;;--- Display the dialog box
  (start_dialog)

  ;;;--- Unload the dialog box
  (unload_dialog dcl_id)

  ;;;--- If the user pressed the Cancel button
  (if(= ddiag 1)
    (princ "\n Sample3 cancelled!")
  )

  ;;;--- If the user pressed the Okay button
  (if(= ddiag 2)
    (progn
      (princ "\n The user pressed Okay!")
    )
  )

  ;;;--- Suppress the last echo for a clean exit
  (princ)

)
 


  Last item.  We need to replace the line in the program: (princ "\n The user pressed Okay!")  with something to modify and display the selected items.  Let's do something simple.  We will tell the user what was selected out of each list.. 

  ;;;--- If the user pressed the Okay button
  (if(= ddiag 2)
    (progn

      ;;;--- Inform the user of his selection from the first list
   
  (princ (strcat "\n You chose " (car retList) " from the first list box."))

      ;;;--- Inform the user of his selections from the second list
     
(princ "\n Your choice(s) from the second list box :")
      (foreach a retList2
        (princ "\n ")
        (princ a)
      )

    )
  )



Add the above to the file, save it and test it out.   Everything working okay?

DCL_PART302.jpg (23575 bytes)

DCL_PART303.jpg (14187 bytes)


 

  When you get your program tested and everything is working, move the blue line above, [ (defun C:SAMPLE3() ] all the way to the top of the file.  This will make all of your variables local and will reset them all to nil when the program ends.

  That's it.  We're done.

Back


AutoLisp Tutorial Home