Steven P Posted March 21, 2019 Posted March 21, 2019 Good afternoon, And with apologies because I am sure this has been asked before, I just can't find it So I have a LISP and I want to either select objects with the mouse or enter an option into the command line and then select the objects, how do you do that? Thanks Quote
dlanorh Posted March 21, 2019 Posted March 21, 2019 Using a selection set for objects / entities. ;This will automatically select all blocks in the drawing (setq ss (ssget "_X" '((0 . "INSERT")))) ;This will allow the selection of Blocks on layer "0" only. Selection can be by any method (pick, crossing, window...) (setq ss (ssget '((0 . "INSERT") (8 . "0")))) You will then need to process the created selection set. Quote
Steven P Posted March 21, 2019 Author Posted March 21, 2019 Thanks dlanorh, but not quite what I was looking for - probably my fault for not writing clear enough. I was after creating an option in the command line along the lines of "Select object or [options]" to create options similar to what you might get if, for example, you copy something "COPY Specify Basepoint or [Displacement mOde] <Displacement>: " where you can click on the drawing or enter text in the command line. Quote
Lee Mac Posted March 21, 2019 Posted March 21, 2019 1 hour ago, Steven P said: I was after creating an option in the command line along the lines of "Select object or [options]" Since you are prompting for selection of multiple objects, you will likely be using the ssget function (or ActiveX equivalent) to acquire the selection. Since the ssget function already accepts keywords to determine the selection method (e.g. Window/Fence/Polygon/Group etc.), you cannot define your own keywords (as you might using initget with one of the getXXX functions) for the user to choose during the selection prompt. One alternative approach might be to allow the user to access an options menu on pressing ENTER/SPACE/right-clicking at the prompt (as opposed to dismissing the prompt via ESC), e.g.: Select objects <options>: This can be easily implemented by evaluating the ssget function using the vl-catch-all-apply function, and testing whether the value returned is a selection set (valid selection), error object (user pressed ESC), or null (user pressed ENTER/SPACE/right-click). The only other possibility that I can think of is to roll your own ssget, in which case you can configure the function to suit any purpose and offer whatever options you like. 2 Quote
Grrr Posted March 21, 2019 Posted March 21, 2019 4 hours ago, Lee Mac said: This can be easily implemented by evaluating the ssget function using the vl-catch-all-apply function, and testing whether the value returned is a selection set (valid selection), error object (user pressed ESC), or null (user pressed ENTER/SPACE/right-click). ^^ Learned something new today, and came up with a short template - (defun C:test ( / s ) (cond ( (vl-catch-all-error-p (setq s (vl-catch-all-apply 'ssget '("_:L-I")))) (alert (vl-catch-all-error-message s)) ) ( s (alert (strcat "\n" (itoa (sslength s)) " selected objects")) ) ( (alert "\nOptions") ) ); cond (princ) ); defun Thanks Lee! Quote
Lee Mac Posted March 21, 2019 Posted March 21, 2019 24 minutes ago, Grrr said: Thanks Lee! You're most welcome @Grrr! To provide some more examples, I've previously used this technique in my Block Counter & Nested Block Counter applications, to allow the user to automatically count all blocks as the default option. Quote
Steven P Posted March 22, 2019 Author Posted March 22, 2019 Thanks Lee, as always a good explanation and I am about to have a look at the 2 examples Grrrrr, thanks, that's given me a start to work on. Quote
Steven P Posted March 28, 2019 Author Posted March 28, 2019 Coming back to this again. Lee can I ask about your CTX / STX copy or swap text functions, these sort of do what I was wanting to do 'Select source text [Settings / Exit]:' How easy would it be to modify these? (at a first look I am not sure how exactly they work) Quote
Lee Mac Posted March 28, 2019 Posted March 28, 2019 1 hour ago, Steven P said: Lee can I ask about your CTX / STX copy or swap text functions, these sort of do what I was wanting to do 'Select source text [Settings / Exit]:' How easy would it be to modify these? Modify in what way? Quote
BIGAL Posted March 28, 2019 Posted March 28, 2019 Steven P I dont understand why you would not just treat the task as two steps select text then do options request. It can be as simple as press enter to continue. Quote
Steven P Posted March 29, 2019 Author Posted March 29, 2019 9 hours ago, BIGAL said: Steven P I dont understand why you would not just treat the task as two steps select text then do options request. It can be as simple as press enter to continue. It would be a simple way to do what I want... but I have my mind set that I want to do it the other way, so partly now I am interested to see if I can get it to do what I want. Lee Sorry, I should be more clear. How easy would it be to take out the copying / swapping part of your CTX routine and leave just the part where it gives the option to enter something in the command line or select on object on the screen? Lots of parts to the LISP that all look integrated together. (I am not asking for a solution, just guidance on how to do it and whether I can use your CTX LISP as a starting point) Quote
Lee Mac Posted March 29, 2019 Posted March 29, 2019 3 hours ago, Steven P said: Lee Sorry, I should be more clear. How easy would it be to take out the copying / swapping part of your CTX routine and leave just the part where it gives the option to enter something in the command line or select on object on the screen? Lots of parts to the LISP that all look integrated together. (I am not asking for a solution, just guidance on how to do it and whether I can use your CTX LISP as a starting point) The selection method used by that program can be boiled down to the following in its simplest terms: (defun c:test ( / sel ) (initget "Settings Exit") (setq sel (entsel "\nSelect an object [Settings/Exit]: ")) ) From there, simply test the result type and branch accordingly: (defun c:test ( / sel ) (initget "Settings Exit") (setq sel (entsel "\nSelect an object [Settings/Exit]: ")) (cond ( (or (null sel) (= "Exit" sel)) (princ "\nUser exited.") ) ( (= "Settings" sel) (princ "\nUser selected Settings.") ) ( (princ "\nUser selected a(n) ") (princ (cdr (assoc 0 (entget (car sel))))) ) ) (princ) ) 1 Quote
Steven P Posted March 29, 2019 Author Posted March 29, 2019 Thanks, that's perfect! I was working through your CTX (and I'll add learnt a couple of things I didn't know along the way) to figure it out. However your mind must be that of an evil genius or so warped no one could follow it easily (well, not me anyway). Thanks 1 Quote
Lee Mac Posted March 29, 2019 Posted March 29, 2019 Glad you could learn from the code @Steven P - of course, this is just one example: there are usually many different ways to write constructions such as this, all equally valid - once you've decided on the behaviour you wish the program to exhibit for the various supplied inputs from the user, you can code the appropriate conditional branches into the program. Quote
Steven P Posted February 21, 2023 Author Posted February 21, 2023 Coming back to this one, 3 years later, there was another question today which prompted me to put an update here. I use Lees code idea a lot for various things, but have added a while loop and errno to keep looping till exit, enter, space is pressed, escape to cancel the LISP. I found in the past that nentsel worked better for me than entsel, the result is a list in the order of selection or options entered. (defun MyTxtSelOptions ( / acount TxtLst msg MyTxt MyNum) (setvar "errno" 0) (setq acount 1) (setq TxtLst (list)) (while (/= 52 (getvar "errno")) (initget "Opt1 Opt2 Opt3 Exit") ; Opt for alphanumeric options (setq msg (strcat "\nSelect Text " (rtos acount) ", or options: [Opt1/Opt2/Opt3/Exit]: ")) (setq MyTxt (nentsel msg) ) (cond ((= 'str (type MyTxt)) ; text entered (setq TxtLst (append TxtLst (list MyTxt))) (princ MyTxt)(princ " Option Chosen") ) ; end cond ((= 'list (type MyTxt)) ; entity selected (setq MyTxt (car MyTxt)) (if (wcmatch (cdr (assoc 0 (entget MyTxt)) ) "*TEXT") ; filter for entity type (progn (setq TxtLst (append TxtLst (list MyTxt))) (setq acount (+ acount 1)) (princ MyTxt) ) (progn ; nothing selected or escaped (princ "No! Text not selected") ) ) ; end if ) ; end cond (t (setvar "errno" 52) ) ; end cond ) ; end conds ) ; end while TxtLst ) and this takes it a little further - not convinced this is entirely correct but seems to work, as above loops till an exit. It adds in some processing if you type in a number and again the result is a list in order you select entities (in these cases texts), options or numbers selected. It won't work with alphanumerical text entry unless it is defined in the initget. I think - and can be corrected - that entering numbers selects entities in the drawing somehow (not something I have done) - and that number can be recorded with the 'lastprompt variable. Entities in the drawing can't be selected with A-Z and so cannot enter them... or something like that. (defun MyTxtSelFreeNum ( / acount TxtLst msg MyTxt MyNum) ; Select entity (text), etnter option or number (setvar "errno" 0) (setq acount 1) (setq TxtLst (list)) (while (/= 52 (getvar "errno")) (initget "Opt1 Opt2 Opt3 Exit") ; Opt_ for alphanumeric options (setq msg (strcat "\nSelect Text " (rtos acount) ", enter a number or options: [Opt1/Opt2/Opt3/Exit]: ")) (setq MyTxt (nentsel msg) ) (cond ((= MyTxt nil) ; gets numbers (if ( = (setq MyNum (substr (getvar 'lastprompt) (strlen msg)) ) "") ; if no number entered (progn ;; if enter or space pressed does this (progn ... ) ) ; end progn (progn (setq TxtLst (append TxtLst (list (atof MyNum)))) ;; If a number is entered (princ MyNum) ) ; end progn ) ; end if ) ; end cond ((= 'str (type MyTxt)) ; Option entered (setq TxtLst (append TxtLst (list MyTxt))) (princ MyTxt)(princ " Option Chosen") ) ; end cond ((= 'list (type MyTxt)) ; entity selected (princ "\n")(princ (strlen (setq MyNum (substr (getvar 'lastprompt) (strlen msg)))) ) (setq MyTxt (car MyTxt)) (if (wcmatch (cdr (assoc 0 (entget MyTxt)) ) "*TEXT") ; filter for entity type (progn (setq TxtLst (append TxtLst (list MyTxt))) (setq acount (+ acount 1)) (princ MyTxt) ) (progn ; The wrong entity type selected (princ "No! Text not selected") ) ) ; end if ) ; end cond (t (setvar "errno" 52) ; escape lop of enter, space, right click ) ; end cond ) ; end conds ) ; end while TxtLst ; a list ) Quote
Recommended Posts
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.