Draw with Dialog Box

Draw with Dialog Box

Lex_van_Ham
Advocate Advocate
2,061 Views
18 Replies
Message 1 of 19

Draw with Dialog Box

Lex_van_Ham
Advocate
Advocate

Hello,

I am new to scripting and I want to make a dialog box with text fields where i can insert a value and then have autocad use that value to make a drawing. I got the box to show everything I want and now I have to get it to actually do something. Can someone help me?

This is what i got so far:Layout Creator.PNG

0 Likes
Accepted solutions (2)
2,062 Views
18 Replies
Replies (18)
Message 2 of 19

Lex_van_Ham
Advocate
Advocate

31 views later and 0 replies so ill retry this question.

So what i want to happen is that the line (and other)  commands are activated using the values from the editboxes when i click OK.

How do i do that?

0 Likes
Message 3 of 19

Moshe-A
Mentor
Mentor

Hi,

 

post the dcl file you have plus any code you already have.

 

moshe

 

0 Likes
Message 4 of 19

Lex_van_Ham
Advocate
Advocate

Thank you for the reply, here is waht i got so far:

 

 

LSP:

(defun C:LayoutCreator ()

(setq dcl_id (load_dialog "Layout Creator.dcl"))

(if (not (new_dialog "LayoutCreator" dcl_id)

);not

(exit)

);if


(setq x (dimx_tile "im")
y (dimy_tile "im"))
(start_image "im")
(fill_image 0 0 x y 5)
(end_image)


(action_tile
"cancel"
"(done_dialog) (setq userclick nil)"
);action_tile

(action_tile
"accept"
(strcat
(progn

"(done_dialog) (setq userclick T)"

(setq Po (get_tile "rb1"))
(setq La (get_tile "rb2"))
(setq B (get_tile "eb1"))
(setq L (get_tile "eb2"))
(setq H (get_tile "eb3"))
(setq K (get_tile "eb4"))
(setq OP (getpoint "\nInsertion point : "))

);progn
);strcat

);action_tile

(start_dialog)

(unload_dialog dcl_id)
(setq OP (getpoint ""))
(command "line" OP B)


(princ)

);defun C:LayoutCreator

(princ)

 

 

 

 

 

DCL:

LayoutCreator : dialog {
label = "Layout Creator" ;

: edit_box {
key = "eb1" ;
label = "Paneel Breedte :" ;
edit_width = 10 ;
}

: edit_box {
key = "eb2" ;
label = "Paneel Lengte :" ;
edit_width = 10 ;
}

: edit_box {
key = "eb3" ;
label = "Paneel Hoogte :" ;
edit_width = 10 ;
}

: edit_box {
key = "eb4" ;
label = "kolommen :" ;
edit_width = 10 ;
}

: edit_box {
key = "eb5" ;
label = "Rijen :" ;
edit_width = 10 ;
}

:boxed_radio_column {
label = "Opstelling" ;

: radio_button {
key = "rb1" ;
label = "Portret" ;
value = "1" ;
}

: radio_button {
key = "rb2" ;
label = "Landscape" ;
}

ok_cancel ;

: row {

: image {
key = "im" ;
height = 1.0 ;
width = 1.0 ;
}

: paragraph {

: text_part {
label = "Designed and Created";
}

: text_part {
label = "By Lex van Ham ";
}
}
}
}
}

0 Likes
Message 5 of 19

Moshe-A
Mentor
Mentor
Accepted solution

hi,

 

In order to respond to any dcl tile (in this case specific to edit_box) you need to call (action_tile) functon inside a while loop scope.

where the test condition of while keeps the dialog ON untill you press the OK button or the Cancel button which by default fires a default callback function that calls (done_dialog x) with 1/0 integer value to return to (start_dialog) function.

 

; next is default autolisp behavior

(done_dialog 1) returns 1 (=ok)

(done_dialog 0) return  0 (=cancel)

 

initilazatizing tiles also must be done inside while scope

 

i only format the code, debuging it is on you Smiley Very Happy

 

cheers,

Moshe

 

 

 

(defun init_tiles ()
 (setq x (dimx_tile "im") y (dimy_tile "im"))
 (start_image "im")
 (fill_image 0 0 x y 5)
 (end_image)
 (setq Po (get_tile "rb1"))
 (setq La (get_tile "rb2"))

 ; do more tiles initilazation here
)

; callback
(defun ctrl_edit_box (value key)
 ; be aware that value is a string, use (atoi) or (atof) to convert it to integer\double numbers.
 ; also check here the validation and range of values
 (if (/= value "")
  (cond
   ((eq key "eb1")
    (setq B value)
   )
   ((eq key "eb2")
    (setq L value)
   )
   ((eq key "eb3")
    (setq B value))
   )
   ((eq key "eb4")
    (setq K value))
   )
  ); cond
 ); if
); ctrl_edit_box 


; callback
(defun ctrl_radio_button (value key)
 (cond
  ((eq key "rb1")
   (setq Po value)
  )
  ((eq key "rb2")
   (setq La value)
  )
 ); cond
); ctrl_radio_button 


(defun C:LayoutCreator (/ dcl_id what_next)
 (setq dcl_id (load_dialog "Layout Creator"))
 (setq what_next 2)
       
 (while (> what_next 1)
  (if (not (new_dialog "LayoutCreator" dcl_id "" '(-1 -1))); open dialog
   (exit)
  )

  (init_tiles); initialize tiles

  ; define callback functions   
  (action_tile "eb1" "(ctrl_edit_box $value $key)")
  (action_tile "eb2" "(ctrl_edit_box $value $key)")
  (action_tile "eb3" "(ctrl_edit_box $value $key)")
  (action_tile "eb4" "(ctrl_edit_box $value $key)")
   
  (action_tile "rb1" "(ctrl_radion_button $value $key)")
  (action_tile "rb2" "(ctrl_radion_button $value $key)")
     
  (setq what_next (start_dialog)); start dialog

  (cond
   ((= what_next 0)
     ; user cancel the dialog, do cleanup here
   )
   ((= what_next 1)
    ; user OK the dialog, do cleanup here
    ; do your work here
    (setq OP (getpoint "\nInsertion point : "))
    (command "line" OP pause "")
   )
  ); cond
 ); while

 (unload_dialog dcl_id)
 (princ)
); C:LayoutCreator 
Message 6 of 19

Lex_van_Ham
Advocate
Advocate

Thanks,

one more thing tho, how do i set the Insertion point (OP) to always be 0,0,0?

0 Likes
Message 7 of 19

Moshe-A
Mentor
Mentor
Accepted solution

(setq OP '(0.0 0.0 0.0))

 

Message 8 of 19

Lex_van_Ham
Advocate
Advocate

Now i have this and everything works except it doesnt like B as a value. when i change it to a number like 123 it works fine and creates a line 123 long starting from 0,0,0 but when i make it B and put 123 in the editbox it says: ; error: bad argument type: numberp: "123"

 

(cond
((= what_next 0)
; user cancel the dialog, do cleanup here
)
((= what_next 1)
; user OK the dialog, do cleanup here
; do your work here
(setq OP '(0.0 0.0 0.0))
(setq P1 (polar OP (dtr 0) B ))
(command "pline" OP P1 )
)
); cond

 

 

0 Likes
Message 9 of 19

Moshe-A
Mentor
Mentor

 

i am sorry but you did not pay attention to what i comment in the (ctrl_edit_box) function

 

 

; callback
(defun ctrl_edit_box (value key)
; be aware that value is a string, use (atoi) or (atof) to convert it to integer\double numbers.
; also check here the validation and range of values

 

all values coming from dialog box are strings and must be converted to numbers if they are not need as strings.

 

also (dtr) is function where it's definition?

 

(setq P1 (polar OP (dtr 0) B ))

 

instead why not to use radians angles?

 

0.0           is "0.00"     degrees

(* pi 0.25) is "45.00"   degrees

(* pi 0.50) is "90.00"   degrees

(* pi 1.50) is "270.00" degrees

 

Moshe

Message 10 of 19

Lex_van_Ham
Advocate
Advocate

i added the dtr function a few minutes ago 

 

(defun dtr (x)
(* pi (/ x 180.0))
)

 

so i can use degrees instead of radians.

Sorry im pretty new to making any type of script as i started trying to understand it last monday. 

Can you explain how i convert the string to integer\double numbers?

0 Likes
Message 11 of 19

Lex_van_Ham
Advocate
Advocate

So im not sure if i used atoi the way its supposed to be used but i think it works:

(setq P1  (polar OP (dtr 0) ( atoi B)))

0 Likes
Message 12 of 19

Moshe-A
Mentor
Mentor

in autolisp documentation take a look at the follwing functions

 

(atoi)       ; convert a string into integer.

(atof)       ; convert a string into a real number (floating-point).

(angtos)   ; convert an angular value in radians into a string, based on angular units

(angtof)   ; convert a string into a real number, based on angular units.

(distof)     ; convert a string that represent a real (floating-point) value into a real value, based on angular units

(rtos)       ; convert a number into a string, based on linear units

 

 

Message 13 of 19

Moshe-A
Mentor
Mentor

@lexvanham123 wrote:

So im not sure if i used atoi the way its supposed to be used but i think it works:

(setq P1  (polar OP (dtr 0) ( atoi B)))


(atoi B) is good (but be aware that if B is "12.98" you will end up with 12)

remenber that (polar) function expect radians angle so converting degrees angle to radians is ok but redundant

 

only when a function is expecting degrees angle you can use (rtd) or (angtos)

 

here is an example:

let's say you select some objects and want to rotate them 45 degrees about 0,0,0

 

(if (setq ss (ssget))

 (command "rotate" "si" ss '(0 0 0) (rtd (* pi 0.25)))  ; or (angtos (* pi 0.25) 0 4) is also good.

)

 

"si" by the way stands for "single" and it's an option of autocad select objects

it saves specifing empty double quotes ("") to respod for the end of select objects in the (command) function

 

 here is the same example without "single"

 

(if (setq ss (ssget))

 (command "rotate" ss "" '(0 0 0) (rtd (* pi 0.25)))  ; or (angtos (* pi 0.25) 0 4) is also good.

)

 

Moshe

 

Message 14 of 19

Moshe-A
Mentor
Mentor

thank you very much for all the 'kudos' you sent me

does your lisp work now?

 

 

0 Likes
Message 15 of 19

Lex_van_Ham
Advocate
Advocate

Yes but i have 1 problem, it sees the R value always as 2 no matter what i type in it.

I made some changes to the code including an array and plines so here is the new one.

(defun init_tiles ()
(setq x (dimx_tile "im") y (dimy_tile "im"))
(start_image "im")
(fill_image 0 0 x y 5)
(end_image)
(setq Po (get_tile "rb1"))
(setq La (get_tile "rb2"))

; do more tiles initilazation here
)

; callback
(defun ctrl_edit_box (value key)
; be aware that value is a string, use (atoi) or (atof) to convert it to integer\double numbers.
; also check here the validation and range of values
(if (/= value "")
(cond

((eq key "eb1")
(setq B (atof value)))

((eq key "eb2")
(setq L (atof value)))

((eq key "eb3")
(setq H (atof value)))

((eq key "eb4")
(setq K (atof value)))

((eq key "eb5")
(setq R (atof value)))

); cond
); if
); ctrl_edit_box

; callback
(defun ctrl_radio_button (value key)
(cond
((eq key "rb1")
(setq Po value)
)
((eq key "rb2")
(setq La value)
)
); cond
); ctrl_radio_button

;This function converts Degrees to Radians.

(defun dtr (x)
;define degrees to radians function

(* pi (/ x 180.0))
;divide the angle by 180 then
;multiply the result by the constant PI

) ;end of function


(defun C:LayoutCreator (/ dcl_id what_next)
(setq dcl_id (load_dialog "Layout Creator"))
(setq what_next 2)

(while (> what_next 1)
(if (not (new_dialog "LayoutCreator" dcl_id "" '(-1 -1))); open dialog
(exit)
)

(init_tiles); initialize tiles

; define callback functions
(action_tile "eb1" "(ctrl_edit_box $value $key)")
(action_tile "eb2" "(ctrl_edit_box $value $key)")
(action_tile "eb3" "(ctrl_edit_box $value $key)")
(action_tile "eb4" "(ctrl_edit_box $value $key)")

(action_tile "rb1" "(ctrl_radion_button $value $key)")
(action_tile "rb2" "(ctrl_radion_button $value $key)")

(setq what_next (start_dialog)); start dialog

(cond
((= what_next 0)
; user cancel the dialog, do cleanup here
)
((= what_next 1)
; user OK the dialog, do cleanup here
; do your work here
(setvar 'clayer "Montagesysteem")
(setq MOP '(0.0 0.0 0.0))
(setq MP1 (polar MOP (dtr 0) (+ (* B K)(* (/ (* B K ) B ) 2 ))))
(setq MP2 (polar MP1 (dtr 90) (+ (+ (* L R) (* (/ (- (* L R) L )L ) 12)) 80)))
(setq MP3 (polar MP2 (dtr 180) (+ (* B K)(* (/ (* B K ) B ) 2 ))))
(setq MP4 (polar MP3 (dtr 270) (+ (+ (* L R) (* (/ (- (* L R) L )L ) 12)) 80)))
(command "pline" MOP MP1 MP2 MP3 MP4 "")
(setvar 'clayer "Panelen")
(setvar 'OSMODE 0)
(setq POP '( 1.0 40.0 0.0 ))
(setq PP1 (polar POP (dtr 0) B))
(setq PP2 (polar PP1 (dtr 90) L))
(setq PP3 (polar PP2 (dtr 180) B))
(setq PP4 (polar PP3 (dtr 270) L))
(command "pline" POP PP1 PP2 PP3 PP4 "")
(command "array" "_last" "" "Rectangular" R K (+ L 12)(+ B 2))
(setvar 'OSMODE 167)

)
); cond
); while

(unload_dialog dcl_id)
(princ)
); C:LayoutCreator

0 Likes
Message 16 of 19

Lex_van_Ham
Advocate
Advocate

Nevermind i found the problem.

i needed to add the line (action_tile "eb5" "(ctrl_edit_box $value $key)")

 

0 Likes
Message 17 of 19

ВeekeeCZ
Consultant
Consultant

@lexvanham123 wrote:

....
(setq MP3 (polar MP2 (dtr 180) (+ (* B K)(* (/ (* B K ) B ) 2 ))))
(setq MP4 (polar MP3 (dtr 270) (+ (+ (* L R) (* (/ (- (* L R) L )L ) 12)) 80)))

(setvar 'OSMODE 0)
(command "pline" MOP MP1 MP2 MP3 MP4 "")  ; << turn the osnaps off for this command as well
(setvar 'clayer "Panelen")
(setvar 'OSMODE 0)
(setq POP '( 1.0 40.0 0.0 ))
(setq PP1 (polar POP (dtr 0) B))
(setq PP2 (polar PP1 (dtr 90) L))
(setq PP3 (polar PP2 (dtr 180) B))
(setq PP4 (polar PP3 (dtr 270) L))
(command "pline" POP PP1 PP2 PP3 PP4 "")
(command "array" "_last" "" "Rectangular" R K (+ L 12)(+ B 2))
(setvar 'OSMODE 167)

...


Also can be used "_none". Then you don't need care about changing OSMODE off and on again.

 

eg. (command "_.RECTANG" "_none" pop "_non" pt2)

 

Anyway, if you use the "PEDIT" its better to use (command "pline" POP PP1 PP2 PP3 "_close")

0 Likes
Message 18 of 19

Lex_van_Ham
Advocate
Advocate

Now i have a new problem... 

I made a new subject for it here:

https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/array-1-row/td-p/7803194

0 Likes
Message 19 of 19

scot-65
Advisor
Advisor

Looking at your attached image, there need not be any action_tiles to any of the

tiles except for OK and Cancel. The accept structure is in the right direction, but

the syntax is a bit off...

 

 

(action_tile
"accept"
(strcat
(progn

"(done_dialog) (setq userclick T)"

(setq Po (get_tile "rb1"))
(setq La (get_tile "rb2"))
(setq B (get_tile "eb1"))
(setq L (get_tile "eb2"))
(setq H (get_tile "eb3"))
(setq K (get_tile "eb4"))
(setq OP (getpoint "\nInsertion point : "))

);progn
);strcat

);action_tile

(action_tile "accept" "(sub-function_call_here)(done_dialog 1)")

 

There can be nothing outside the second set of quotes inside the action_tile statement.

There can only be a total of 4 quotes inside action_tile. If more, they require escaping [\"].

 

You cannot use GETPOINT in this manner while inside action_tile. Take advantage of the

integer return from done_dialog to start dialog --> to enter in the "main" execution portion

of your code. Also, technically, the dialog is closed at the time you are trying to setq and

therefore the values you wish to fetch are already gone. Also, flip your "cancel" and add

a 0 to it's done_dialog.

 

Use the sub-function call to setq all the variables as I show, then call (done_dialog 1).

 

(setq sd (start_dialog))

 

then,

 

(if (and sd (= sd 1) (setq OP (getpoint "\nSpecify insert point: ")))

 (progn

  ...

 );progn

);if

 

 
load dialog
new dialog
 initialize
 set tile
 mode tile
 action tile
done dialog
start dialog
unload dialog

???

 


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

0 Likes