Hi,
This one always seams to elude my logic...
I am able in lisp to create a command prompt selection menu, easy (see code below).
However what I want is for the lisp to be ready to undertake an action UNLESS I select an option.
An example is the offset command wich has a function ready to roll (namely the specify offset distance) "OR" I can interrupt the "specify offset distance" and enter one of the sub options (in the case of offset Through/ Erase/Layer).
My code attempts to offset also, UNLESS the user wishes to specify a distance.
How do I achieve this?
(DEFUN C:loadoffset () ;CREATING MENU FOR SUB COMMANDS [GETIT] [GOTIT]... (setq choose (getstring "\nSelect an option... [1=GET DIST] [2=GOTDIST]: ")) (if (or (equal choose "1"))(GETIT)) (if (or (equal choose "2"))(GOTIT)) ;TERMINATING SELECTION MENU... ) (defun getit ( gotit ) (setq MYDIST (getdist "\n SELECT A DISTANCE: ")) (gotit) ) (defun gotit () (command "_offset" MYDIST pause pause"exit") )
Solved! Go to Solution.
Solved by alanjt_. Go to Solution.
looks nice but i fail to see where this answers my question.
as an example of what im trying to create type offset and the command prompt echos a list of options however at the same time the usser can ignore the options and contine specifying the offset distance. this egnore and conine witha defult option is what im after
@Anonymous wrote:....what I want is for the lisp to be ready to undertake an action UNLESS I select an option.
An example is the offset command wich has a function ready to roll (namely the specify offset distance) "OR" I can interrupt the "specify offset distance" and enter one of the sub options (in the case of offset Through/ Erase/Layer).
My code attempts to offset also, UNLESS the user wishes to specify a distance.
....
If I'm understanding you correctly, this sounds like another job for (initget) and its keyword option. Try this:
(defun C:test (/ user)
(prompt
(strcat
"\nOffset distance = "
(if (= (getvar 'offsetdist) -1)
"Through"
(rtos (getvar 'offsetdist))
); if
"."
); strcat
); prompt
(initget "Distance Through")
(setq user (getpoint "\nSelect object to offset or <Distance/Through>: "))
(cond
((listp user); picked a point - apply it as selection in Offset
(command "_.offset" "" user pause "")
); picked-a-point condition
((= user "Distance")
(command "_.offset" (getdist) pause pause "")
); distance condition
((= user "Through")
(command "_.offset" "_through" pause pause "")
); Through condition
); cond
); defun
The user can just pick an object if they like the current Offset distance that's displayed, without needing to confirm that first with Enter/space, as in regular Offset. Only if they type a D [or a d or more of the word Distance] or a T [or a t or more of the word Through], if they want to specify one of those options, will it allow entry other than picking a point, and proceed accordingly.
It does have the drawback that it shows the crosshairs without the pick box for the first prompt, rather than the pickbox without the crosshairs as in regular Offset. That may well be fixable, but see what you think of the rest.
Perhaps I'm missing something, but how is this different from the normal offset command?
@alanjt_ wrote:Perhaps I'm missing something, but how is this different from the normal offset command?
Normal Offset requires you to accept or designate the offset distance, before you can pick something to Offset. This lets your first action be to pick something if the distance is right, and only if you want to change the distance, call for whichever option you want [D to give a new Distance, T to use Through].
It also ends after Offsetting only one thing, just because the OP's original did. That could certainly be adjusted to let you Offset as many things as you like, possibly by just eliminating the final "" Enters and leaving you in the Offset command, if the returned nil doesn't cause problems [I haven't tried it].
Ok, I can see your attempt now (I am confused how you plan to select an object with getpoint), but that's different from the op's request of just having a global variable (last offset distance/option) or specifying a distance.
This?
(defun c:test (/ ent) (if (setq ent (entsel "\nSelect object to offset: ")) (progn (command "_.offset" (progn (initget "Through") (cond ((getdist (strcat "\nSpecify offset distance or [Through] <" (if (minusp (getvar 'OFFSETDIST)) "Through" (rtos (getvar 'OFFSETDIST)) ) ">: " ) ) ) ((getvar 'OFFSETDIST)) ) ) ent PAUSE ) (while (eq (logand 1 (getvar 'CMDACTIVE)) 1) (command "")) ) ) (princ) )
@alanjt_ wrote:Ok, I can see your attempt now (I am confused how you plan to select an object with getpoint), but that's different from the op's request of just having a global variable (last offset distance/option) or specifying a distance.
This is how it selects an object with (getpoint):
....
(setq user (getpoint "\nSelect object to offset or <Distance/Through>: "))
(cond
((listp user); picked a point - apply it as selection in Offset
(command "_.offset" "" user pause "")
); picked-a-point condition
....
It does it via (getpoint) because that's one of the functions that honors keywords specified in (initget), so you can give it a point or type in a keyword initial, either is accepted as input, and it proceeds appropriately for either. Looking at Help for (initget), I see that (entsel) also honors keywords [I had forgotten that--my gut feeling was that only (get...) functions were in the list], so it could probably be done using that, too.
The routine is designed, to quote the OP,
"... to offset ... UNLESS the user wants to specify a distance."
But I may have misunderstood the intent.
initget works with all get* functions (excluding getstring) and entsel, nentsel and nentselp.
I guess I'm just confused on the intent, but since it's not my code, forget about it.
@alanjt_ wrote:This?
....
When I run that, it still requires me to take the step of accepting or designating the distance [or Through option] -- it only moves that required step from before I pick an object [as normal Offset does it] to after. My impression was that the OP didn't want to have to take that step at all, unless they wanted to change the distance, in which case they would call for an option.
Also, if the default is Through, and I hit Enter to accept that, I get an error:
Value must be positive and nonzero.
; error: Function cancelled
In reference to the original post by The_Caddie. When I look at your code and follow your description of the functionality that you want based upon the Offset command, I am still fuzzy on what you are looking for exactly. I believe what you are looking for is looping functionality that allows the user to continue placing offsets at the orginally specified offset distance unless the user decides to enter a new offset value. You want to be able to add functionality to the built-in offset command that allows you to change the offset distance on the fly instead of having to exit and re-enter the offset command.
In reference to the posts by Kent1Cooper and alanjt_. It sounds like you both are bit confused on the intent as I have been, but have kind of settled into the same frame of thought. As said above, I think the only real advantage is to be able to change the offset distance within an offset command.
So I took The_Caddie program and adding functionality to the gotit function:
(DEFUN C:loadoffset ()
;CREATING MENU FOR SUB COMMANDS [GETIT] [GOTIT]...
(setq choose (getstring "\nSelect an option... [1=GET DIST] [2=GOTDIST]: "))
(if (equal choose "1")(GETIT))
(if (equal choose "2")(GOTIT))
;TERMINATING SELECTION MENU...
)
(defun getit ( )
(setq MYDIST (getdist "\n SELECT A DISTANCE: "))
(gotit)
)
(defun gotit ( )
(initget "1 Exit")
(while
(null
(setq item (entsel "\nSelect object to offset or [1=GET DIST/Exit]: "))
)
)
(cond
(
(= item "1")
(getit)
)
(
(= item "Exit")
(princ "Exiting Lisp Command\n")
)
(
(/= item "Exit")
(progn
(command "_offset" MYDIST item pause "exit")
(gotit)
)
)
)
)
Not that this covers all thrown errors but it does allow for changing of the offset distance while still staying in the lisp command.
What about this?
(defun c:TEst (/ *error* cmd ent) (defun *error* (msg) (and cmd (setvar 'CMDECHO cmd)) (if (and msg (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*QUIT*,"))) (princ (strcat "\nError: " msg)) ) ) (setq cmd (getvar 'CMDECHO)) (setvar 'CMDECHO 0) (initget "Distance Through") (if (setq ent (entsel (strcat "\nSelect object to offset " (if (minusp (getvar 'OFFSETDIST)) "through" (rtos (getvar 'OFFSETDIST)) ) " or [Distance/Through]: " ) ) ) (progn (cond ((eq ent "Through") (princ "\nSelect object to offset or [Exit/Undo] <Exit>: ") (command "_.offset" ent) ) ((eq ent "Distance") (princ (strcat "\nSpecify offset distance or [Through/Erase/Layer] <" (if (minusp (getvar 'OFFSETDIST)) "Through" (rtos (getvar 'OFFSETDIST)) ) ">: " ) ) (command "_.offset") ) (T (princ (strcat "\n" (if (minusp (getvar 'OFFSETDIST)) "Specify through point or [Exit/Multiple/Undo] <Exit>: " "Specify point on side to offset or [Exit/Multiple/Undo] <Exit>: " ) ) ) (command "_.offset" "" ent) ) ) (setvar 'CMDECHO 1) (while (eq (logand 1 (getvar 'CMDACTIVE)) 1) (command PAUSE)) ) ) (*error* nil) (princ) )
this is more like it. This has a menue with a command ready to go UNLESS i choose through witch will bring me to another part of the program...
NICE
THNX-
@Anonymous wrote:.... I am still fuzzy on what you are looking for exactly. I believe what you are looking for is looping functionality that allows the user to continue placing offsets at the orginally specified offset distance unless the user decides to enter a new offset value. You want to be able to add functionality to the built-in offset command that allows you to change the offset distance on the fly instead of having to exit and re-enter the offset command.
....
If that's what's wanted, I remembered seeing something like that on Cadalyst CAD Tips, and I found it. I haven't compared, but see what you think:
http://cadtips.cadalyst.com/2d-operations/multiple-offsets