Jump to content

DCL Execute program on button press


TemporaryCAD

Recommended Posts

I am building a DCL interface for inserting multiple blocks at once.  I have a core DCL window where you select what you want to insert.  These buttons popup a new window where specific information is entered to select each insertion.  

 

At the end, code should be ran that handles the entered information and the user selects the insertion point.  

 

I believe it's the (getpoint) function that is causing trouble.  I found an example of how to do this via hiding the dialog, but I want to close it.  Essentially, I want the DCL component of the code to completely finish before running the insertion function.  

 

Please let me know if you know of a solution or a resource you could point me to.  Thank you!

Link to comment
Share on other sites

I am not sure if this is the best way, I tend to use the DCL method of creating them on the fly (I think Lee Mac has examples of this), so the DCL coding is a part of the LISP routine and file. Not sure if this works if you have a separate DCL file but it should work.

 

You can use action_tile to add a value to a variable, for example

(action_tile "DoingThis" "(setq DoneThis \"Yes\")" ) noting for a string you need the \" combination within the Action_tile " "s. Also possible to build lists and so on

You can add several variables here

(action_tile "DoingThis" "(setq DoneThis \"Yes\") (setq ANumber 123456)" )

and also a function

(action_tile "DoingThis" "(AFunction)" )

 

You probably know this

 

When you click the OK button on a DCL the box closes but the LISP calling it continues to run, so you can save all the user inputted data as variables, finish and close the DCL as required then continue from there with a getpoint

 

 

Hope that makes sense, it worked for me OK on the ones I made up

Link to comment
Share on other sites

11 minutes ago, Steven P said:

When you click the OK button on a DCL the box closes but the LISP calling it continues to run, so you can save all the user inputted data as variables, finish and close the DCL as required then continue from there with a getpoint

Does this only work for OK buttons?  

 

When I try to close dcl in a command, I'll put both unload_dialog and MyFunction in the action tile field.  This leads to me getting an error (see attached).

 

I'm clearly doing something wrong! - thanks for the help.  

dclerror.PNG

Link to comment
Share on other sites

I'm going to share some more details in hopes of finding a solution.  

 

Here's the basic line:

  (action_tile "build" "(term_dialog) (execute)")

Where execute is the function I am trying to run.  

 

This leads to the error pictured above.  

 

However, when I run: 

 

  (action_tile "build" "(term_dialog)")

Everything works fine.  

 

I think the problem is related to getpoint, and I'm not really sure why.  Any help is greatly appreciated!

Link to comment
Share on other sites

In your action_tile you could put something like (action_tile "build" "(setq to-do \"insert\")(done_dialog)")

at the very last line(s) of your routine you could then put something like :

 ...your code

 (cond

   ((eq to-do "insert")(go-insert-yourself))

   ((eq to-do "script")(go-script-yourself))

   (t (princ ""\nComputer says bye"))

  );end con

); end of your function

Edited by rlx
  • Like 1
Link to comment
Share on other sites

First a comment that in my LISPs containing a DCL I have them (action_tile  "Build" "(execute) (term_dialogue)") not sure if the order makes a difference.

 

Here is one thing that I have used

 

(action_tile "build" "(setq MyAction \"Evaluate\")(done_dialog)")


...
...



(eval (list (read "MyAction")))

 

This was from a DCL box where the user can choose what to run, their selected LISP is saved as a variable and then run later

Edited by Steven P
  • Like 1
Link to comment
Share on other sites

term_dialog in itself isn't necessarily a problem but its a little crude , like a dragon in a porcelain cabinet 😉 ...  it better should only be used in your error handling routine as a final act of desperation. You cannot run commands while a dialog is active , well , not normal autocad commands anyway that involve screen interaction. There is a way around this using vla-commands but thats beyond the scope of this thread.

  • Like 1
Link to comment
Share on other sites

4 hours ago, Steven P said:

First a comment that in my LISPs containing a DCL I have them (action_tile  "Build" "(execute) (term_dialogue)") not sure if the order makes a difference.

 

Here is one thing that I have used

 

(action_tile "build" "(setq MyAction \"Evaluate\")(done_dialog)")


...
...



(eval (list (read "MyAction")))

 

This was from a DCL box where the user can choose what to run, their selected LISP is saved as a variable and then run later

 

This worked!  

 

Thank you so much!

 

I was working through this thread in order of easiest to hardest.  I tried swapping the order of commands (didn't work) and the alluded to (vla-sendcommand) function (still led to the same problem). 

 

However (eval (list ( /string of command name incl parentheses /))) works perfectly.  This is my initial time using eval in this way, and it's quite awesome - it's the first time I've felt lisp can do something better than another language.  

 

This has been a great learning experience.  

  • Like 1
Link to comment
Share on other sites

RLX answer makes sense to what I did before now (sometimes I get a LISP working through brute force, try enough combinations of stuff and one will work eventually).

 

With (evaluate) first in the list that will fail - can't pick a point with the dialog box open

With (done_dialog) first, might be that when the dialog is closed and action_tile isn't applicable any more - no DCL, No more actions possible, can't go to the next part (evaluate)

 

or something like that

 

So take the call to the LISP outside of the dialogue box and off you go.

 

 

 

(For future reference, a bit fiddly but it is possible to save all user entered data as a variables, as above, close the dialog if you need the user to go to the drawing, and then afterwards open a new instance of the dialog box, populating it with the variables you just saved away)

Link to comment
Share on other sites

I don't want to make a new topic, but how does autolisp DCL handle (action_tile) when you add more than one command?

 

Right now, I'm working on a code that checks if information is input and disables the button until the required info is present.  

 

(defun check()
  (if (not (vl-some '(lambda (x) (eq x "")) (list test1 test2)))
    (progn
      (mode_tile "build" 0)
      (if (= (read (get_tile "tog1")) 1)
        (progn
          (if (not (vl-some '(lambda (x) (eq x "")) (list test3 test4)))
            (mode_tile "build" 0)
            (mode_tile "build" 1)
          )
        )
      )
    )
  )
)

 

This takes a list of vars - test1 test2 in example - and enables build when both are present (I'm initializing strings to "" as a global var).  Then, it checks if a toggle box is active, and if so requires additional information.  

 

The code works - almost.  

 

The following is the toggle box and edit box (action_tile) code:

 

(action_tile "tog1" "(toggle $value) (check)")
(action_tile "editbox1" "(check) (setq test1 $value)")
(action_tile "editbox2" "(setq test2 $value) (check)")
(action_tile "editbox3" "(setq test3 $value) (check)")
(action_tile "editbox4" "(setq test4 $value) (check)")

 

The toggle works perfectly.  The edit boxes do not.  They will not update upon receiving a value, but will update the next time they run.  

i.e. Fill in box 1 - > fill in box 2 -> build is still disabled.  At this point, even clicking in box 1 will enable build, but it will not do once both fields are populated - it takes one more step.  

 

Please advise!

Link to comment
Share on other sites

With the limits from above (cannot do stuff on the drawing with the DCL box open), you should be able to do multiple actions, whether it is a few commands of setq or whatever

 

Is "editbox1" in your sample meant to be the opposite way to the others?

 

 

 

Are you able to make up a sample of your code to post here to see what is happening? I might get chance to make something up later and test a couple of things for you,. but work keeps getting in the way

 

 

Link to comment
Share on other sites

Don't know if this will help you out at all:

 

Looking my second LISP below first. dcltest (), it makes a very quick DCL on the fly using what I understand from your info above:

4 edit boxes, a toggle and a button. Hopefully I will have called these the same as you have? 

There is a mode_tile to disable the button.

Action tiles,  instead of your $value I have put in a (get_tile \".....\"). I changed the order of your tog1 and editbox1 so that the value updates and then the check is made (in the case that the user has enough to enable build, then the user deleted info in editbox1). The setq parts are in there still by way of example (see below why)

 

That's all that is

 

 

Next part I have re-written your check. Since the DCL is still open I can get the values of tiles directly in this LISP - not needing global variables, duplicating what I did in the action_tiles setting test1 to test4. Test1 to test4 are set here to avoid errors (such as global variables affecting this, or whatever), left in the action_tiles to show that you can do that.

 

I am not great at Lambdas so going simple with 'if' commands. I think the return from toggle is a string (?) "1" or "0". Then some 'if' commands to work it out. If either editbox1 or editbox2 has an input AND editbox3 or editbox4 then enable the button

 

 

So have a look and see if you can get what you need from this?

 

 

 

(defun check (  / )
  (setq test1 (get_tile "editbox1"))
  (setq test2 (get_tile "editbox2"))
  (setq test3 (get_tile "editbox3"))
  (setq test4 (get_tile "editbox4"))
  (setq test5 (get_tile "tog1"))

  (if (or (= test5 "")(= test5 "0"))
    (princ test5)
    (if (and (or (= test1 nil)(= test1 "")) (or (= test2 nil)(= test2 "")) )
      (mode_tile "build" 1)
      (if (and (or (= test3 nil)(= test3 "")) (or (= test4 nil)(= test4 "")) )
        (mode_tile "build" 1)
        (mode_tile "build" 0)
      )
    )
  )
)


(defun c:dcltest ( / )



;;;;;SAMPLE DCL;;;;;;;;;;
  (if (strcat (getvar "TEMPPREFIX") "LH.dcl")(vl-file-delete (strcat (getvar "TEMPPREFIX") "LH.dcl")))  ;;Delete DCL if it exists
  (setq fo (open (setq fname (vl-filename-mktemp "LH" (getvar "TEMPPREFIX") ".dcl")) "w")) ;;Make temp file
  (write-line "ddgetvalAH : dialog {" fo) ;;open temp file
  (write-line "  key = \"Lispdialoguebox\";" fo)
  (write-line "  label = \"Dialogue Box\";" fo)
  (write-line "  spacer;" fo)
  (write-line " :row {alignment = top;" fo)

  (write-line "   :boxed_column { label = \"\"; label = \"Edit Box\"; " fo)
  (write-line "    :row {alignment = middle;" fo)
  (write-line "      : edit_box { key = \"editbox1\"; width = 5; fixed_width = true;}" fo)
  (write-line "      : edit_box { key = \"editbox2\"; width = 5; fixed_width = true;}" fo)
  (write-line "      : edit_box { key = \"editbox3\"; width = 5; fixed_width = true;}" fo)

  (write-line "      : edit_box { key = \"editbox4\"; width = 5; fixed_width = true;}" fo)
  (write-line "    }" fo)

  (write-line "   :boxed_column { label = \"Toggle\"; " fo)
  (write-line "    :row {alignment = middle;" fo)
  (write-line "      : toggle {label = \"tog1\"; key = \"tog1\";}" fo)
  (write-line "    }" fo)
  (write-line "  }" fo)

  (write-line "    :boxed_column { label = \"Buttons\"; width = 30; " fo)
  (write-line "      :row {alignment = top; width = 20;" fo)

(write-line (strcat ":button { key = \"build\"; label = \"Build\"; is_default = false; fixed_width = true; is_cancel = true; width = 15; }") fo)

  (write-line "      }" fo)
  (write-line "    }" fo)
  (write-line "  }" fo)
  (write-line "  }" fo)
  (write-line "}" fo)

  (close fo) ;;close temp file

  (setq dcl_id (load_dialog fname)) ;load temp file
  (if (not (new_dialog "ddgetvalAH" dcl_id))
    (exit)
  )
;;;;;END SAMPLE DCL;;;;;;;;;;

  (mode_tile "build" 1)
  (action_tile "tog1"     "(setq toggle (get_tile \"tog1\"))    (check)" )
  (action_tile "editbox1" "(setq test1 (get_tile \"editbox1\")) (check)" )
  (action_tile "editbox2" "(setq test2 (get_tile \"editbox2\")) (check)" )
  (action_tile "editbox3" "(setq test3 (get_tile \"editbox3\")) (check)" )
  (action_tile "editbox4" "(setq test4 (get_tile \"editbox4\")) (check)" )
  (action_tile "Build"    "(done_dialog 1)")

  (start_dialog)
  (unload_dialog dcl_id)
  (vl-file-delete fname)


)

 

Edited by Steven P
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...