DCL and dynamic block

DCL and dynamic block

Anonymous
Not applicable
1,889 Views
10 Replies
Message 1 of 11

DCL and dynamic block

Anonymous
Not applicable
Hello, I thought I may get a better response here in the correct forum. iv got a short code that inserts a dynamic block and prompts for specific values. I'm trying to integrate it with a dialogue box, in which I have length and height in edit_boxes. I can't seem to get the values to change the variables to what is required to drive the block. The original codes I used are below, iv adapted them slightly by integrating the DCL and supporting lisp into the dynamic insert code on my computer but whatever I try I couldn't get them to work together.

All I want is a dialogue box that asks for some values then puts in the correct block and applies the parameters.

Can someone guide me in the correct direction please.

This is the DCL part iv pulled
http://www.afralisp.net/dialog-contr...ted-part-2.php

And here is the lisp I found elsewhere

(defun c:wldsym ()
(vl-load-com)
(setq osnapold (getvar "osmode"))
(setq dimsc (getvar "dimscale"))
(setq nAme (getstring "\nSymbol: "))
(setq pnt1 (getpoint "\nPoints to: "))
(setq pnt2 (getpoint pnt1 "\nSelect end of leader: "))
(setvar "cmdecho" 0)
(setvar "osmode" 0)
(command "-insert" nAme pnt1 dimsc "")
(setq b1 (vlax-ename->vla-object (entlast)))
(setq props (vlax-safearray->list (vlax-variant-value (vla-getdynamicblockproperties b1))))
(foreach prop props
(if (= (vla-get-propertyname prop) "Position1 Y")
(vla-put-value prop (cadr p2))
);if
(if (= (vla-get-propertyname prop) "Position1 X")
(vla-put-value prop (car p2))
);if
);foreach
(setvar "osmode" osanpold)
(setvar "cmdecho" 1)
(princ)
)
0 Likes
Accepted solutions (1)
1,890 Views
10 Replies
Replies (10)
Message 2 of 11

scot-65
Advisor
Advisor

You will need to create a section of code just for interacting with the DCL file.

I have attached a simple starting template I use when creating DCL type projects.

 

One item to remember is you will be taking a "snapshot" of the current DCL state

and, as a suggestion, saving the values as a LIST when pressing the OK button.

 

When designing the DCL, avoid user input of text, especially reals or integers. If possible

provide a list_box or popup_list so the user makes a selection. This may or may not work for you.

 

Once past the DCL part of the code, execute your program by referencing from this LIST.

In lieu of using car, cadr, etc., use nth instead.

 

I and others here can help you during development.

 

???

 


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

0 Likes
Message 3 of 11

Anonymous
Not applicable

Thanks for your help. Below is the lisp i have, Iv tried allsorts to get the variables to insert into the parameters. I do need to be able to enter my own value in the dialogue box so a dropdown is out im afraid. Iv attached what i have for my dcl.

 

(defun c:InsSec ( / osnapold dimsc nAme pnt1 b1 props)


   (vl-load-com)
   (SecUI)
   (setq nAme "Angle Section")
   (setq pnt1 (getpoint "\nInsertion Point: "))
   (setvar "cmdecho" 0)
   (command "-insert" nAme pnt1 1 "" "")
  


(setq b1 (vlax-ename->vla-object (entlast)))

(setq props  (vlax-safearray->list (vlax-variant-value (vla-getdynamicblockproperties b1))))

(foreach prop props
  (if (= (vla-get-propertyname prop) "Distance")
    (vla-put-value prop depth)
    );if
  (if (= (vla-get-propertyname prop) "Distance1")
    (vla-put-value prop height)
    );if
  );foreach

   (setvar "cmdecho" 1)

  (princ)

)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;----------------------------;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;----------------------------;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;----------------------------;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun SecUI ( / UI_id)
 
(setq dcl_id (load_dialog "UI.dcl"))
     (if (not (new_dialog "SecUI" dcl_id))
  (exit)
     );if
 
;(set_tile "Depth" "")
(mode_tile "Depth" 2)
(action_tile "Depth" "(setq depth $value)")

;(set_tile "Height" "")
(mode_tile "Height" 0)
(action_tile "Height" "(setq height $value)")


(action_tile "accept" "")

(start_dialog)
(unload_dialog UI_id)
 

 
(princ)


)

0 Likes
Message 4 of 11

smaher12
Advocate
Advocate
Accepted solution

See if this helps...

 

(defun c:InsSec ( / nAme pnt1 b1 props)
  (vl-load-com)
  (setvar "cmdecho" 0)

  (defun dfaults ()

  ; =============== Dialog Menu Presets ===============
    (if (= depth nil) (setq depth 5))
    (if (= height nil) (setq height 7))

  ; =============== Dialog Menu Callback ===============
    (if depth (set_tile "depth" (rtos depth 2 1)))
    (if height (set_tile "height" (rtos height 2 1)))

  );dfaults

   (activate)
   (setq nAme "Angle Section")
   (setq pnt1 (getpoint "\nInsertion Point: "))
   (command "-insert" nAme pnt1 1 "" "")
  
   (setq b1 (vlax-ename->vla-object (entlast)))
   (setq props  (vlax-safearray->list (vlax-variant-value (vla-getdynamicblockproperties b1))))
   (foreach prop props
     (if (= (vla-get-propertyname prop) "Distance")
       (vla-put-value prop depth)
      );if
     (if (= (vla-get-propertyname prop) "Distance1")
       (vla-put-value prop height)
      );if
    );foreach
   (setvar "cmdecho" 1)
  (princ)
);inssec

(defun activate ()
  (setq dcl_id (load_dialog "inssec.dcl"))
  (if (not (new_dialog "inssec" dcl_id))
    (exit)
  )

  (dfaults)
  (action_tile "depth" "(setq depth (distof $value))")
  (action_tile "height" "(setq height (distof $value))")
  (action_tile "accept" "(done_dialog)")
  (action_tile "cancel" "(exit)")
   (start_dialog)
    (unload_dialog dcl_id)
 
 (princ)
);activate
inssec : dialog {
            label = "Drawing Info";

   spacer;
    :column {
	: edit_box {
	  label = "Depth:";
	  mnemonic = "D";
	  key = "depth";
	  edit_width = 10;
	  allow_accept = false;
	}
	: edit_box {
	  label = "Height:";
	  mnemonic = "H";
	  key = "height";
	  edit_width = 10;
	  allow_accept = false;
	}
    } // end boxed_column

    ok_cancel;
} // end inssec dialog
Message 5 of 11

scot-65
Advisor
Advisor

Smasher seems to have it figured out.

Back to the concept of taking a "snapshot" of the dialog, this is what I would do:

 

from:
... (dfaults) (action_tile "depth" "(setq depth (distof $value))") (action_tile "height" "(setq height (distof $value))") (action_tile "accept" "(done_dialog)") (action_tile "cancel" "(exit)") (start_dialog) (unload_dialog dcl_id) to:
... (dfaults) (action_tile "accept" "(InsSec_GET)(done_dialog 1)") (action_tile "cancel" "(done_dialog 0)") (setq sd (start_dialog)) (unload_dialog dcl_id) where: (defun InsSec_GET () (setq depth (distof (get_tile "depth"))) (setq height (distof (get_tile "height"))) );end InsSec_GET back in your main program, test if SD=1 and execute (I think "exit" is ugly):
(SecUI) (if (= sd 1) (progn ... );progn );if

done_dialog returns an integer to the start_dialog.

Let's take advantage of this by trapping it and using it to dictate the flow of the program.

Since you only have 2 items to fetch, a LIST would not be necessary.

I do not see a test if the entered values are valid. Inside InsSec_GET is where you can perform this.

When either of the values is not proper, display an alert that the value(s) are not correct and assign

a default value to the depth or height.

 

Of course there are other methods...

 


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

0 Likes
Message 6 of 11

Anonymous
Not applicable
Smaher that's spot on thanks, I've got options to adapt this which would require more inputs. I've never built a list, and this is the first time I've ever used DCL.

I'm unsure at what the dialogue callback does...

Do you have some guidance on building a list please, I'm guessing you do it instead of assigning to variables? I think I've got how to retrieve from a list using the nth command.

I will put in some validation as you mention Scot.

When my block is inserted the values are passed and the geometry is changed but the dimensions are not.
I've had to put in 2 parts at the end
(command "dimregen")
(command "regen")
To get the block dimensions to update, is this the best way to do this?
0 Likes
Message 7 of 11

Anonymous
Not applicable
Also scot what are you gaining from doing the dialogue using your alternate method?
If never used progn either.

I'm keen to learn not just grab code. 😀
0 Likes
Message 8 of 11

scot-65
Advisor
Advisor

I have several programs where the data gathered from a DCL is quite extensive (more than 15 values).

The advantage to the LIST method is that you have one and only one variable "floating around".

 

With this variable, as shown in the template I supplied, storage for next use where the values are already

set and can be reinitialized. "Remember for next time".

In determining where to store these values depends on the type of program.

 

I'll try for two (very simple) examples where data is stored and can be retrieved for the next session:

-  Building Site Data - Address, Lot, Block. The values gathered can be stored in the drawing file itself via VLAX-LDATA-PUT.

-  User Settings - OSMODE. This can be stored in SETCFG, which is user/loginname type information.

Other storage methods are available.

 

Now, from your example, let's build a list:

(defun GET ()

 (setq MyValues (list

  (get_tile "width")

  (get_tile "depth")

 ))

);end GET

 

Checkboxes, popup lists, list boxes, radio buttons and other such type of user input controls can be stored in this list.

Remember what I said about taking that "snapshot" of the DCL state upon exiting?

 

In the initialization section of the DCL section, check if the stored list is in fact declared. If not, then create a default list.

In the set tile section, populate the values to the corresponding tiles.

 

Once past the DCL section of the program you now have one variable with all the information needed.

To access this list, use (nth # MyValues). The first position of this list is 0.

 

It took several DCL builds to see the light and building a LIST is now my preferred method regardless of how few items to fetch.

 

Yes, the light bulb above did turn on!

 

scot-65

 


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

Message 9 of 11

smaher12
Advocate
Advocate

Your welcome. The "dialog callback" is the section where the program retains the users entered data. The following should help you get started on a list box.

 

(defun c:abc ()

  (defun dfaults ()

  ;;; =============== Dialog Menu Presets ===============
    (if (= circle1 nil) (setq circle1 1))
    (setq mylist '("1.0" "2.0" "3.0"))
    (if (= circle2 nil) (setq circle2 "1"))

  ;;; =============== Dialog Menu Callback ===============
    (if circle1 (set_tile "circle1" (rtos circle1 2 1)))
    (set_tile "circle2" (if circle2 circle2 (setq circle2 "0")))

    (start_list "circle2")
      (mapcar 'add_list mylist)
        (end_list)
  );end dfaults

   (activate)
   (setq p1 (getpoint "\nSelect point: "))
   (command "._circle" p1 circle1
            "._circle" p1 (nth (atoi circle2) mylist))
 (princ)
);end abc

  (defun activate ()
    (setq dcl_id (load_dialog "abc.dcl"))
      (if (not (new_dialog "abc" dcl_id))
        (exit)
      )

  (dfaults)
   (action_tile "circle1" "(setq circle1 (distof $value))")
   (action_tile "circle2" "(setq circle2 $value)")
   (action_tile "accept" "(done_dialog)")
   (action_tile "cancel" "(exit)")
    (start_dialog)
     (unload_dialog dcl_id)
      (princ)
   );end activate
abc : dialog {
            label = "DCL Test";

   spacer;
    : boxed_column {
      label = "Circle Diameters";
	: edit_box {
	  label = "Circle One:";
	  key = "circle1";
	  edit_width = 10;
	  allow_accept = false;
	}
        : popup_list { 
          label = "Circle Two:"; 
          key = "circle2";
          edit_width = 8; 
        }
    } // end boxed_column

    ok_cancel;
} // end abc dialog
0 Likes
Message 10 of 11

Anonymous
Not applicable
Thanks guys, I'm slowly getting there and have learnt some useful things. So far if got a dialog box with a few inputs in edit boxes. Iv also got an image in there made from a slide.

I had some trouble with creating a list as it constantly returned nil nil....... In the end it turned out to be me using the label instead of the key for the get_tile command.

Ive tidied it up after a lot of trial and error, I'm going to put some validation in there soon. I've got a couple more steps I'd like to try now.

1. Is it possible to populate a list box with the visibilities of a block before placing it then choose the DCL to load based on the selection made? So I want to have a small DCL with 2 list boxes, 1 will have a list of blocks then the other will have the visibilities of the selected block. When these are selected another dcl will load and have the appropriate values for that block visibility combo.

2. I've been trying to use something like (entsel) and vla-get-property values so i can then select a block and populate a list with the values from it I've previously input. So I can then put these into a different block. I think I've got to check for the property then, if true, extract the value and add ,append?, it to a list. Am I anywhere near with this?
0 Likes
Message 11 of 11

scot-65
Advisor
Advisor
The geometry for stored lists from your thoughts is doable.
First gather desired DFX's of a particular block into a list then
construct a "dotted pair" of the list with the block name.

I don't have a clear example, but have one for you...
(setq a nil)
(setq b (list "Apples" "Oranges"))
(setq a (cons "Fruit" (cons b a)))
=
("Fruit" ("Apples" "Oranges"))

(car (car (cdr a))) = "Apples"

???

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

0 Likes