Get Dialog Box Values in LISP

Get Dialog Box Values in LISP

isrsol702
Enthusiast Enthusiast
4,165 Views
16 Replies
Message 1 of 17

Get Dialog Box Values in LISP

isrsol702
Enthusiast
Enthusiast

Hello AutoCAD Gurus,

 

I have  lips routine to create beam end views. The thing about it is that I have to input all the information over every time I run the lisp routine and most of the values I have to input are repetitive. so my question is,

 

is there a way to create a dialog box to input the values and have it run the lisp routine and when I call it back to create the next beam end view, it will bring back the same values I previously inputted and just change some of the values per the new beam endview?

 

Here is an example of the values I need to input

 

Enter slab thickness, return if none: 5

 

Enter L[left], R[right] or C[centered] to locate slab with respect to beam: C

 

Enter beam depth from top of slab in inches: 35

 

Enter beam width at bottom of beam in inches: 18

 

Enter beam width at top of beam in inches, return if same as bottom: 20

 

Enter T if top beam width is at top of slab, B if at bottom of slab: T

 

Enter the height of the cgs above beam bottom in inches: 25

 

Enter the total number of anchors required w/ suffix to indicate type -
[D=deadend, S=stressend, I=intermediate or U=unspecified] eg - 8D: 8S

 

Enter R or C to designate rectangular or circular column, return if none: R

 

Enter size of column face at beam end in decimal inches: 24

 

Is column vertical rebar evenly spaced? [Y or N]: Y

 

How is column located w/ respect to beam [C=centered, L=left justified, R=right
justified or O=offset]: C

 

Enter rebar quantity & size at rectangular column face or total no. of bars for
circular column [eg 3#7]: 3#8

 

Pick lower left corner of endview:

 

After that last command I pick any place on my drawing and it will create the end view.  then to create a new one, I have to input all the values all over again even if some of them are the same. Please help

 

0 Likes
4,166 Views
16 Replies
Replies (16)
Message 2 of 17

Anonymous
Not applicable

I created something similar to what you are talking about.

 

The idea is to give default values (The ones you use the most). But also, in your code make it so that the values do not become nil after each use, which will allow you to use the same numbers over again in the same drawing. (see below for example)

 

(defun c:bob ( / )
  (if (not myvariable)
    (setq myvariable 5))
  (if (setq newVariable (getint (strcat "\nEnter a new number " "<" (itoa myvariable) ">: ")))
    (setq myvariable newVariable))
  
  )
Message 3 of 17

Kent1Cooper
Consultant
Consultant

Yes, you can do that with DCL programming.  See here and adjacent/linked entries.

Kent Cooper, AIA
0 Likes
Message 4 of 17

isrsol702
Enthusiast
Enthusiast

Pardon my ignorace Kent,

 

I read the link you sent to me, I clicked on other link with in the link to related topics to find out where do I start to create the dialog box, a lot of terms used, I do not quite understand. could you be so kind as to point me in the right direction? thank you

0 Likes
Message 5 of 17

isrsol702
Enthusiast
Enthusiast

zraboin thank you for your answer, I am very novice at this, I have tweaked a couple of thing on some of the lisp routine I use to make them more useful, but I'm no where at the level you are at. can you please tell me how to apply the code you sent to me?

0 Likes
Message 6 of 17

Kent1Cooper
Consultant
Consultant

@isrsol702 wrote:

Pardon my ignorace Kent, .... where do I start to create the dialog box, a lot of terms used, I do not quite understand. ....


I haven't dug into using DCL myself either, so others are better able to help there.  You could "climb up the ladder" in the Help hierarchy and find the best starting point.  But....

 

If DCL is too daunting, an approach like @Anonymous's suggestion is something I've done, in which case you just hit Enter through most of the prompts to accept the defaults except where you want a different value. In this case that's a lot of Enters to plow through, so you may want to investigate DCL anyway.

 

But I like to do that default-offering approach in a way that takes more code, but  A) doesn't require temporary variables [their newVariable in addition to their myVariable], and  B) prevents invalid responses, and  C) won't allow you to hit Enter when there's no default value set yet unless you have a starting default you want to offer.

 

For something with a common value that you want to offer as an initial default even when you haven't used the routine yet, let's say your slab thickness of 5:

 

(initget 6); no zero, no negative
(setq *BEslabthk
  ; global variable [the * is not needed -- just one way of "marking" a global variable]
  ; using *BE to start all of them to tie them to this & avoid conflict with other routines
  (cond
    ( (getdist ; returns nil on Enter so it will go to next condition
        (strcat
          "\nSlab thickness <"
          (rtos (cond (*BEslabthk) (5.0)))
            ; offer prior value if present, otherwise 5, shown in current units format/precision
            ; assuming a real number rather than an integer -- could be 6.5, for instance?

            ; using (getdist ) means you can pick points on-screen, or enter feet-inches-fractions, etc.
          ">: "
        ); strcat
      ); getdist
    ); end User-input condition
    (*BEslabthk); on Enter above, use prior value if present
    (5.0); none-of-the-above -- if no User input or prior value, use initial default
  ); cond
); setq

 

For something without a common-enough value to offer as an initial default, let's say your beam depth:

 

(initget (if *BEbeamd 6 7)); no zero, no negative, no Enter on first use when there's no prior value
(setq *BEbeamd
  (cond
    ( (getdist
        (strcat
          "\nBeam depth"
          (if *BEbeamd (strcat " <" (rtos *BEbeamd) ">") "")
            ; build offering of prior value only if present, otherwise nothing
          ": "
        ); strcat
      ); getdist
    ); end User-input condition
    (*BEbeamd); on Enter above, use prior value
      ; [no none-of-the-above value, since Enter is prohibited with no prior value]
  ); cond
); setq

 

Similar approaches can be used with (getkword) for limited specific options such as Top/Bottom. For could-be-anything text-string values that can't be done with (initget)/(getkword), such as your "3#8", you have to handle it a little differently, because hitting Enter in response to a (getstring) function doesn't return nil as (getdist) & (getkword) & (getint) etc. do, but an actual text string that just has nothing inside it -- "".

Kent Cooper, AIA
Message 7 of 17

Anonymous
Not applicable

I would have to see your code, but what's happening is it is checking to see if the variable is already declared if so it is giving the user the option to just hit enter to use that variable or to enter a new one.

 

I'm assuming your code starts off something like this:

 

(defun c:functionName ( / variablesHere)

(setq slabThickness (getint "\nEnter slab thickness, return if none: "))

....

)

instead, you would remove the variables that could stay declared from the top line, then checked to see if they are declared as such:

 

(defun c:functionName ( / )

  (if (not slabThickness)
    (setq slabThickness 0)) ;set a preset variable here if the function has not been run before
  
(setq slabThickness (if (setq newSlabThickness (getint (strcat "\nEnter slab thickness, return if <" (itoa slabThickness) ">: ")))
		      newSlabThickness
		      slabThickness)); checks to see if the user wants a new slab thickness or if they want the default

....

)

 

Message 8 of 17

isrsol702
Enthusiast
Enthusiast

I attached my lisp routine just in case you need to see what it looks like

0 Likes
Message 9 of 17

scot-65
Advisor
Advisor

Looks like an interesting DCL exercise.

 

Weather you decide to remain on the command line input mode or use the dialog,

the basic structure is the same.

 

Concept:

Start with a gremlin. The gremlin will be a LIST.

If the gremlin does not exist, generate it before proceeding.

Each index position in the gremlin is one saved value for your program.

When it is time to select a point on the screen, rebuild the gremlin list.

 

I'll structure this simple example as if it is a DCL (but without the DCL file itself)...

 

(defun User_GET ()
 (setq USER_MyFunction (list
  (get_tile "Rad100")
  (get_tile "Edi200")
  (get_tile "Tog300")
 ))
)

(if (new_dialog "CODE" (setq dcl_id (load_dialog "CODE.dcl")))
 (progn
  ;*** INITIALIZE ***
  (or USER_MyFunction (setq USER_MyFunction (list "Rad101" "Test" 0)))
  ;*** SET TILE ***
  (set_tile "Rad100" (nth 0 USER_MyFunction))
  (set_tile "Edi200" (nth 1 USER_MyFunction))
  (set_tile "Tog300" (nth 2 USER_MyFunction))
  ;*** MODE TILE ***

;*** ACTION TILE *** (action_tile "accept" "(User_GET)(done_dialog 1)") (action_tile "cancel" "(done_dialog 0)") (setq sd (start_dialog))
(unload_dialog dcl_id)(setq dcl_id nil) );progn );if (if (= sd 1) (progn ;*** Execute Main Program *** );progn );if (setq sd nil)(princ)

Now the trick here is to have the user make selections instead of typing

a value [edit box] where possible. List boxes and popup lists are a little

complicated to convert at this early stage, I will just mention this now.

 

Sketch out the design of the dialog before actually attempting to build it.

I go thru at least 3 iterations before starting.

Treat the dialog as if it is only gathering information; and not perform any

of the actual calculations. User input is isolated from the actual main program.

 

Disclaimer: untested.

 

I'm here to assist you and at the same time educate others in this community.

 


Scot-65
A gift of extraordinary Common Sense does not require an Acronym Suffix to be added to my given name.

Message 10 of 17

isrsol702
Enthusiast
Enthusiast

Thank you Scot-65, I will try it as soon as I get a chance.

0 Likes
Message 11 of 17

pbejse
Mentor
Mentor

@isrsol702 wrote:

....command prompt default values, I'm not quite sure what's best, all I need is to cut the time to input the values over an over again ;)


As not to disturb your current code too much, we will just add two subfunctions and a default dynamic list for you but you need to do all the dirty work plus  I really don't have the time to spare fiddling with the rest of the code  Smiley Happy

 

.....
(or InitVal
    (setq InitVal
           '(("ST" . 5) ("SJ" . "C") ("BD" . 35) ("BW" . 18) ("TW" . 18) ("DIMTOP" . "T") ("CGS" . 25)
             ("NA" . "8S") ("COLSHAPE" . "R") ("COLSIZE" . 24) ("EVEN" . "Y") ("COLJUST" . "C")
             ("BARS" . "3#8") ("SF" . 8) ("COVER" 1.5) ("REBCOV" . 2.0) ("MINOPEN" . 2.5) ("ANCHOUT" . 3))
      )
    )      
(defun _assocvalue  (v s / x)
      (setq x (cdr (assoc v InitVal)))
      (if s x (vl-princ-to-string x))
      )
(defun _UpdateList (n v)
      (if (/= (_assocvalue n t) v)
          (setq InitVal (subst (cons n v)(assoc n InitVal) InitVal)))
      v
      )
....      

 

 

And this is the usage. ( getreal ) / ( getkword ) / ( getstring )

 

 

....
(setq bd (getreal (strcat "\nEnter beam depth from top of slab in inches < "  (_assocvalue "BD" nil)" >: ")))
(setq bd (if (null bd) (_assocvalue "BD" t)(_updatelist  "BD" bd )))

(setq bw (getreal (strcat "\nEnter beam width at bottom of beam in inches< " (_assocvalue "BW" nil) " >: " )))
(setq bw (if (null bw) (_assocvalue "BW" t)(_updatelist  "BW" bw )))

...

(progn
          (initget "T t B b")
          (setq dimtop (getkword
                             (strcat "Enter T if top beam width is at top of slab, B if at bottom of slabs< " (_assocvalue "DIMTOP" nil) " >: " )))
          (setq dimtop (if (null dimtop) (_assocvalue "DIMTOP" t)(_updatelist  "DIMTOP" dimtop )))
       
       )
...

 

HTH

 

 

Have fun isrsol702, and tell us how it goes.

 

Message 12 of 17

pbejse
Mentor
Mentor

@pbejse wrote:
.....As not to disturb your current code too much, we will just add two subfunctions and a default dynamic list for you .....

I'm a retard, I'm making simple things needlessly complicated, and because of that, i will help you build a dialog for your default values. Does this sound good to you?

Hang in there.
Message 13 of 17

roland.r71
Collaborator
Collaborator

 

If you are new to it, creating a dialog might be a bit much, as you don't need it. (looks good, and is usually more userfriendly, of course)

 

Here's a snippet as how i do it with just the commandline, for in this case asking for a color (=layer)

 

With this example, the global *uc* (User Choice) 'remembers' the last selection (as it doesn't get reset, like a local var), so all you have to do the next time is hit enter, or click the option, as you can enter the choice by more then one way. (you can even use the arrow keys for selecting if you have a dynamic prompt).

 

If there's no previous choice, "R" (Red) is set as default.

 

   (defun selRGB ( / )
      (initget "R G B")
      (setq *uc*
         (cond
            ((getkword (strcat "\nChoose [Red/Green/Blue] <" 
               (setq *uc* (cond (*uc*) ("R"))) ">: "))
            ) (*uc*)))
      (cond
         ; do some stuff based on choice.
      )
   )

 

Message 14 of 17

scot-65
Advisor
Advisor

FWIW...

 

CBSG01.jpg

 

???

 


Scot-65
A gift of extraordinary Common Sense does not require an Acronym Suffix to be added to my given name.

Message 15 of 17

pbejse
Mentor
Mentor

@scot-65 wrote:

FWIW...

 


Very nice scot-65

 

Way nicer than what I drafted Smiley Happy

 

Capture.PNG

 

 

 

 

Message 16 of 17

pbejse
Mentor
Mentor

FWIW;

Command prompt default [ patterned after post #6 of 15 <Kent1Cooper> ]

 

 

(defun _default (itm msg n s)
	(setq f (cond
                      ( (= n 1) getint)
                      ( (= n 2) getstring)
                      ( (= n 3) getkword))
              )
      	(setq itmstr itm);<	
	(if (null s)(initget (if itm 2 3)))
	(setq itm
	  (cond
	    ( (f
	        (strcat
	          "\n" msg
	          (if itm (strcat " <" (vl-princ-to-string itm) ">") "")
	            
	          ": "
	        )
	      )
	    )
	    (itm)
	  )
	)
	(if (and (= n 2)(eq itm "")) itmstr itm)
)

 

HTH

 

Try the attached modified code.

Message 17 of 17

scot-65
Advisor
Advisor

pbejse,

 

As I mentioned in a earlier response, I will sit down and draft

the dialog (a minimum of) three times before actually creating

the DCL file. For this exercise, it was during commercial breaks

during Perry Mason (Friday) and Svengoolie (Saturday).

 

See attached file of the third iteration.

 

One item that I set precedence for is to not let the user enter

values into an edit box, especially integers and reals. Having to

test these value can be challenging, depending on the situation.

VL_STRING_TRIM helps, but not foolproof.

 

🙂

 

Scot-65

 


Scot-65
A gift of extraordinary Common Sense does not require an Acronym Suffix to be added to my given name.