Author Topic: Minimum Clicks with ssget  (Read 13858 times)

0 Members and 1 Guest are viewing this topic.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« on: September 11, 2004, 03:07:53 PM »
Trying to create a routine to do the following:

Get a TEXT object,
  If not a text object use the point picked as the first corner
  of a selection box to get a selection set of text objects.
 
problem using entsel is that if nul a point is not returned
 
This is how I solved the problem but was wondering if someone had a
better or differant solution.
Code: [Select]
(defun c:test (/ ent pt pt2 idx ss)
  (while ; loop until point is picked
    (not
      (setq
        pt (getpoint "\nSelect Text to Increment or select a group of text.")
      )
    )
     (princ "\nPlease try again...")
  )

  (cond
    ;;=================================================
    ((setq ss (ssget pt '((0 . "TEXT,MTEXT"))))
     ;; user picked a text object
     (setq ent (ssname ss 0))
     (if (cdr (assoc 3 (entget ent)))
       (prompt "\nMTEXT is too large, not supported!")
       (prompt "\nGot a single text object.")
     ) ; endif
    ) ; end cond 1

    ;;=================================================
    ;; No text selected so get a selection set
    ((and (setq pt2 (getcorner pt)) ; user to pick window corner
          (setq ss (ssget "_C" pt pt2 '((0 . "TEXT,MTEXT"))))
     )
     (setq idx (sslength ss)) ; got some text objects
     (while (>= (setq idx (1- idx)) 0)
       (setq ent (ssname ss idx))
       (if (cdr (assoc 3 (entget ent)))
         (prompt "\nMTEXT is too large, not supported!")
         (prompt "\nGot a sel set of text objects.")
       ) ; endif
     ) ; end while
    ) ; end cond 2

    ((prompt "\n*-*  Not Text, Try again. *-*")
    ) ; end cond 3
  ) ; end cond stmt
  (princ)
)

If you use
Code: [Select]
(cond
  ((setq ss (ssget ":S" '((0 . "TEXT,MTEXT")))))
  ((setq ss (ssget '((0 . "TEXT,MTEXT")))))
)

The user has to click twice to start the second ssget
If you use
Code: [Select]
((setq ss (ssget '((0 . "TEXT,MTEXT")))))
you have to click twice to get a single text object.

Any ideas?
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Minimum Clicks with ssget
« Reply #1 on: September 12, 2004, 12:06:03 AM »
Actually it looks like a viable solution to me
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #2 on: September 12, 2004, 09:25:31 AM »
Thanks Keith,
I was hoping there was some vlax magic that would give you the point
data from a entsel when it missed an object.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

SMadsen

  • Guest
Minimum Clicks with ssget
« Reply #3 on: September 12, 2004, 10:10:31 AM »
I agree with Keith.

To get a pickbox cursor, you could use the SSGET ":E" method but it probably needs additional handling.

I noticed you're using a crossing for an empty pick but GETCORNER acts as a window method. Calling INITGET with 32 can give you the dashed appearance that crossing uses.
Another enhancement could be to handle pickfirst selections.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #4 on: September 12, 2004, 11:24:28 AM »
Thanks Stig for the comments.
The _C was a cut & paste error, I'm such a slow typest & do a lot of Cut & paste.
Thanks for the initget 32 tip.
And by 'Pick First' you are refering to the ssget pt where it may pick up more
than one if text is overlapping? If so I added ( and ( = (sslength ss) 1))
to handle that.


Code: [Select]
(defun c:test (/ ent pt pt2 idx ss)
  (while ; loop until point is picked
    (not
      (setq
        pt (getpoint "\nSelect Text to Increment or select a group of text.")))
     (princ "\nPlease try again...")
  )

  (cond
    ;;=================================================
    ((and (setq ss (ssget pt '((0 . "TEXT,MTEXT"))))
          (= (sslength ss) 1)); if >1 force user to get a set
     ;; user picked a text object
     (setq ent (ssname ss 0))
     (if (cdr (assoc 3 (entget ent)))
       (prompt "\nMTEXT is too large, not supported!")
       (prompt "\nGot a single text object.")
     ) ; endif
    ) ; end cond 1

    ;;=================================================
    ;; No text selected so get a selection set
    ((and (null (initget 32))
          (setq pt2 (getcorner pt)) ; user to pick window corner
          (setq ss (ssget "_W" pt pt2 '((0 . "TEXT,MTEXT"))))
     )
     (setq idx (sslength ss)) ; got some text objects
     (while (>= (setq idx (1- idx)) 0)
       (setq ent (ssname ss idx))
       (if (cdr (assoc 3 (entget ent)))
         (prompt "\nMTEXT is too large, not supported!")
         (prompt "\nGot a sel set of text objects.")
       ) ; endif
     ) ; end while
    ) ; end cond 2

    ((prompt "\n*-*  Not Text, Try again. *-*")
    ) ; end cond 3
  ) ; end cond stmt
  (princ)
)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

Crank

  • Water Moccasin
  • Posts: 1503
Minimum Clicks with ssget
« Reply #5 on: September 12, 2004, 11:25:44 AM »
I also would expect the pickbox cursor.

Isn't it easier to make a selection and filter the text objects?
Vault Professional 2023     +     AEC Collection

SMadsen

  • Guest
Minimum Clicks with ssget
« Reply #6 on: September 12, 2004, 11:34:03 AM »
CAB, with pickfirst I mean gripped entities as returned by SSGETFIRST.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #7 on: September 12, 2004, 11:43:46 AM »
Quote from: SMadsen
CAB, with pickfirst I mean gripped entities as returned by SSGETFIRST.


Wow..
That went right over my head :shock:
I don't see how ssgetfirst applies.

Are you talking about the user seleting a set or object before starting the routine?
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #8 on: September 12, 2004, 11:49:52 AM »
Quote from: Crack
I also would expect the pickbox cursor.

Isn't it easier to make a selection and filter the text objects?

Crank

The intent of the routine was to have it in a loop so the user could either
pick each text item in the order they wanted OR to select the group of text.
I was trying to eliminate the need for the second click, that is if the user
in making the first pick, picked a non-text object or picked nothing that the
point they picked would be used as the first point in the window to get the
selection set.

Perhaps I was trying to be too fancy.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

SMadsen

  • Guest
Minimum Clicks with ssget
« Reply #9 on: September 12, 2004, 12:18:35 PM »
Quote from: CAB
Are you talking about the user seleting a set or object before starting the routine?

Yes, but it was only a suggestion for enhancement, is all. You know, chit-chat   :D

Just cooked this up as a possible filter for a pickfirst set:

Code: [Select]
(defun getpickfirst (lst / ss a ent)
  (cond ((setq ss (cadr (ssgetfirst)))
         (setq a 0)
         (repeat (sslength ss)
           (and (setq ent (ssname ss a)
                      a   (1+ a))
                (not (member (cdr (assoc 0 (entget ent))) lst))
                (ssdel ent ss)(setq a (1- a))
           )
         )
        )
  )
  (if (and (= (type ss) 'PICKSET)(/= 0 (sslength ss))) ss)
)

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #10 on: September 12, 2004, 01:16:28 PM »
Quote from: SMadsen
Yes, but it was only a suggestion for enhancement, is all. You know, chit-chat   :D

Ok,
I think i understand your lisp :) , I commented it & moved the AND.

this routine would allow the user to select a set prior to starting
the lisp that would then exclude any object type not in your list.

Code: [Select]
;;   Pourpose:
;;   To filter a preselected selection set for object types
;;   listed in the variable list lst
(defun getpickfirst (lst / ss a ent)
  ;;  lst is a list of object types like ("TEXT" "MTEXT")
  (cond ((setq ss (cadr (ssgetfirst))) ; get previously selected sel set
         (setq a 0) ; set pointer
         (repeat (sslength ss) ; foreach object in sel set
           (setq ent (ssname ss a) ; get obj name
                 a   (1+ a)) ; increment counter
           ;; is obj not a member of the list ?
           (and (not (member (cdr (assoc 0 (entget ent))) lst))
                (ssdel ent ss); if not a member remove it from ss
                (setq a (1- a)) ; and deincrement pointer
           ) ; and
         ); repeat
        ) ; end cons 1
  ) ; end cond stmt
  ;; if ss is a pick set and has objects then return the selection set
  (if (and (= (type ss) 'PICKSET)(/= 0 (sslength ss))) ss)
  ;;  else return nil because when IF fails it returns nil
); end defun


Test call:
Code: [Select]
(defun c:test(/ ss)
  (setq ss (getpickfirst (list "TEXT" "MTEXT")))
  (princ)
)


Very nice, Thanks CAB
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #11 on: September 12, 2004, 01:34:11 PM »
Here is the revised routine

Code: [Select]
(defun c:test (/ ent pt pt2 idx ss got_ss)
  ;; function to process the selection set
  (defun got_ss (ss / idx ent)
    (setq idx (sslength ss)) ; got some text objects
    (while (>= (setq idx (1- idx)) 0)
      (setq ent (ssname ss idx))
      (if (cdr (assoc 3 (entget ent)))
        (prompt "\nMTEXT is too large, not supported!")
        (prompt "\nGot a sel set of text objects.")
      ) ; endif
    ) ; end while
  ) ; end defun

  ;;  test for valid pre selected selection set
  (if (null (setq ss (getpickfirst (list "TEXT" "MTEXT"))))
    ;;  no set so get user input
    (while ; loop until point is picked
      (not
        (setq
          pt
           (getpoint "\nSelect Text to Increment or select a group of text.")))
       (princ "\nPlease try again...")
    )
  ) ; endif

  (cond
    ;;=================================================
    (ss ; selection already made
     (got_ss ss) ; process the selection set
    ) ; end cond 1
   
    ;;=================================================
    ((and (setq ss (ssget pt '((0 . "TEXT,MTEXT"))))
          (= (sslength ss) 1)
     ) ; if >1 force user to get a set
     ;; user picked a single text object
     ;;(setq ent (ssname ss 0))
     ;;(if (cdr (assoc 3 (entget ent)))
     ;;  (prompt "\nMTEXT is too large, not supported!")
     ;;  (prompt "\nGot a single text object.")
     ;;) ; endif
     (got_ss ss) ; process the selection set
    ) ; end cond 2

    ;;=================================================
    ;; No text selected so get a selection set
    ((and (null (initget 32))
          (setq pt2 (getcorner pt)) ; user to pick window corner
          (setq ss (ssget "_W" pt pt2 '((0 . "TEXT,MTEXT"))))
     )
     (got_ss ss) ; process the selection set
    ) ; end cond 3

    ((prompt "\n*-*  Not Text, Try again. *-*")
    ) ; end cond 3
  ) ; end cond stmt
  (princ)
); end defun
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

JohnK

  • Administrator
  • Seagull
  • Posts: 10640
Minimum Clicks with ssget
« Reply #12 on: September 12, 2004, 06:57:39 PM »
As far as the selecting the objects already selected; Go to my web site and check out the Selected-p and Get-Selected functions. I worked out some some prety cool code. Monday ill see if i cooked up any beter versions that i didnt post.
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

SMadsen

  • Guest
Minimum Clicks with ssget
« Reply #13 on: September 12, 2004, 08:01:07 PM »
A link would be nice, John :D

CAB, here's a little alternative method to play with. It allows for normal exit by the user and returns either a text entity or a selection of text - or nil if exited, of course. Try it out.

Code: [Select]
(defun picktext (/ ent pt2 resp ss)
  ;; check if: 1. not an insert, 2. text or mtext?
  (defun chkpick (ent)
    (if (and (<= (length ent) 2)
             (member (cdr (assoc 0 (entget (car ent))))
                     '("TEXT" "MTEXT")
             )
        )
      (car ent)
    )
  )
  ;; init loop
  (setq resp T)
  ;;  test for valid pre selected selection set
  (if (or (zerop (getvar "PICKFIRST"))
          (null (setq ss (getpickfirst (list "TEXT" "MTEXT")))))
    ;;  no set so get user input
    (while resp
      ;; prompt user
      (prompt "\nSelect object(s): ")
      ;; grread with pickbox cursor and no tracking
      (setq resp (grread nil (+ 2 4 8) 2))
      ;; user clicked a point?
      (cond
        ((= (car resp) 3)
         ;; go look for entity at clicked point
         (cond ((setq ent (nentselp (cadr resp)))
                ;; got a text ent? save it and exit loop
                (and (setq ent (chkpick ent)) (setq resp nil))
               )
               ;; otherwise, make a window selection and see what you got
               ((setq pt2 (getcorner (cadr resp)))
                                        ; user to pick window corner
                ;; got a text selection? save it and exit loop
                (and (setq
                       ss (ssget "_W" (cadr resp) pt2 '((0 . "TEXT,MTEXT")))
                     )
                     (setq resp nil)
                )
               )
         )
        )
        ;; user hit space or return?
        ((= (car resp) 2)
         (and (member (cadr resp) '(13 32)) (setq resp nil))
        )
      )
    )
  )
  ;; return entity or selection set
  (cond (ent)(ss))
)

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #14 on: September 12, 2004, 08:10:17 PM »
Quote from: Se7en
As far as the selecting the objects already selected; Go to my web site and check out the Selected-p and Get-Selected functions. I worked out some some prety cool code. Monday ill see if i cooked up any beter versions that i didnt post.


I removed some extra code from your function.

Code: [Select]
(defun Get-Selcted (/ x idx xlist)
  ;; x is nil if nothing is already selected
  (if (setq x (cadr (ssgetfirst)))
    (progn ; at least one obj in x
      ;;(sssetfirst nil)
      (setq idx (sslength x))
      (while (>= (setq idx (1- idx)) 0)
        ;;  make a list
        (setq xlist (cons (ssname x idx) xlist))
        ;;(redraw (ssname x idx) 3)
      ); end while
      (if(>(length xlist)1) xlist (car xlist))
    ); progn
    ;; ELSE need to select something
    (progn
      (while (not (setq x (entsel "\nselect object: "))))
      (redraw (car x) 3)
      (car x) ; return entity
    ); progn
  ); endif
); defun

(defun c:test(/ a)
  (setq a (get-Selcted))
  (princ)
)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #15 on: September 12, 2004, 08:15:01 PM »
Thanks Stig.
I'll try it out in the am...
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

SMadsen

  • Guest
Minimum Clicks with ssget
« Reply #16 on: September 13, 2004, 10:45:03 AM »
Here's a slightly extended version. Type L for Last or S for something else ;)

Code: [Select]
(defun picktext (/ ent pt2 resp ss)
  ;; check if: 1. not an insert, 2. text or mtext?
  (defun chkpick (ent)
    (if (and (<= (length ent) 2)
             (member (cdr (assoc 0 (entget (car ent))))
                     '("TEXT" "MTEXT")
             )
        )
      (car ent)
    )
  )
  ;; init loop
  (setq resp T)
  ;;  test for valid pre selected selection set
  (if (or (zerop (getvar "PICKFIRST"))
          (null (setq ss (getpickfirst (list "TEXT" "MTEXT"))))
      )
    ;;  no set so get user input
    (while resp
      ;; prompt user
      (prompt "\nSelect object(s): ")
      ;; grread with pickbox cursor and no tracking
      (setq resp (grread nil (+ 2 4 8) 2))
      ;; user clicked a point?
      (cond
        ((= (car resp) 3)
         ;; go look for entity at clicked point
         (cond
           ((setq ent (nentselp (cadr resp)))
            ;; got a text ent? save it and exit loop
            (and (setq ent (chkpick ent)) (setq resp nil))
           )
           ;; otherwise, make a window selection and see what you got
           ((setq pt2 (getcorner (cadr resp)))
                                        ; user to pick window corner
            ;; got a text selection? save it and exit loop
            (and (setq ss (ssget "_W" (cadr resp) pt2
                                 '((0 . "TEXT,MTEXT"))))
                 (setq resp nil)
            )
           )
         )
        )
        ;; user hit space or return?
        ((= (car resp) 2)
         (and (member (cadr resp) '(13 32)) (setq resp nil))
         ;; user hit L/l for Last?
         (and (member (cadr resp) '(76 108))
              (setq ent (chkpick (list (entlast))))
              (setq resp nil)
         )
         (and (member (cadr resp) '(83 115))
              (princ (vl-list->string '(10 83 101 55 101 110 32 105
                                       115 32 119 101 105 114 100))))
        )
      )
    )
  )
  ;; return entity or selection set
  (cond (ent)(ss))
)

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #17 on: September 13, 2004, 11:11:34 AM »
Stig you're very clever. 8)
You got the pick box using grread.

Nice touch with L but S had me LOL.


I think this routine is a keeper.

Perhaps calling picktext with a list of types would make the routine more
universal.  ( picktext ( list "TEXT" "MTEXT"))
And it might need the prompt passed to it as well ( picktext types prmpt )

All in all a very good job. I like it. :D
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

SMadsen

  • Guest
Minimum Clicks with ssget
« Reply #18 on: September 13, 2004, 11:54:09 AM »
Quote from: CAB
Nice touch with L but S had me LOL.

Not quite in compliance with standard GUI but what the heck  heh

Quote from: CAB
Perhaps calling picktext with a list of types would make the routine more universal.  ( picktext ( list "TEXT" "MTEXT"))
And it might need the prompt passed to it as well ( picktext types prmpt )

Excellent idea.

Thanks for the comments.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #19 on: September 13, 2004, 01:07:15 PM »
Stig,
Here is what I got so far but got stuck on the rephrasing of
 ( "TEXT" "MTEXT")   to ( 0 . "TEXT,MTEXT")

And what to do if the user wants ALL types of objects. ? nil filter

Updated with Stigs code..

Code: [Select]
;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
;;; FUNCTION
;;;   To filter a preselected selection set for object types
;;;   listed in the variable list lst
;;;
;;; ARGUMENTS
;;;   lst -> a list of object types like ("TEXT" "MTEXT")  
;;;
;;; USAGE
;;;   (setq ss (getpickfirst typs))
;;;
;;; PLATFORMS
;;; 2000+
;;;
;;; AUTHOR
;;; Copyright© 2004 S. Madsen
;;; http://www.smadsen.com/
;;;
;;; VERSION
;;; 1.0 Sep. 13, 2004
;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
(defun getpickfirst (lst / ss a ent)
  ;;  lst is a list of object types like ("TEXT" "MTEXT")
  (cond ((setq ss (cadr (ssgetfirst))) ; get previously selected sel set
         (setq a 0) ; set pointer
         (repeat (sslength ss) ; foreach object in sel set
           (setq ent (ssname ss a) ; get obj name
                 a   (1+ a)
           ) ; increment counter
           ;; is obj not a member of the list ?
           (and (not (member (cdr (assoc 0 (entget ent))) lst))
                (ssdel ent ss) ; if not a member remove it from ss
                (setq a (1- a)) ; and deincrement pointer
           ) ; and
         ) ; repeat
        ) ; end cons 1
  ) ; end cond stmt
  ;; if ss is a pick set and has objects then return the selection set
  (if (and (= (type ss) 'pickset) (/= 0 (sslength ss)))
    ss
  )
  ;;  else return nil because when IF fails it returns nil
) ; end defun


;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
;;; FUNCTION
;;;   To filter a preselected selection set for object types
;;;   listed in the variable list lst
;;;
;;; ARGUMENTS
;;;   typs is a list of exceptable onject types
;;;   prmpt is the prompt string to use for user select
;;;
;;; USAGE
;;;  (setq ss (picktext (list "TEXT" "MTEXT")"\nSelect object(s): "))
;;;
;;; PLATFORMS
;;; 2000+
;;;
;;; AUTHOR
;;; Copyright© 2004 S. Madsen
;;; http://www.smadsen.com/
;;;
;;; VERSION
;;; 1.0 Sep. 13, 2004
;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
(defun picktext ( typs prmpt / ent pt2 resp ss)
  ;;  typs is a list of exceptable onject types
  ;;  prmpt is the prompt string to use for user select
 
  ;; check if: 1. not an insert, 2. text or mtext?
  (defun chkpick (ent)
    (if (and (<= (length ent) 2)
             (member (cdr (assoc 0 (entget (car ent)))) typs)
        )
      (car ent)
    )
  )

  ;;  phrase the typs list from ("TEXT" "MTEXT")
  ;;  to (0 . "TEXT,MTEXT")
  (defun sstypes (lst / str)
    (cond ((not lst) (cons 0 "*"))
          ((setq str "")
           (foreach n lst
             (setq str (strcat n "," str))
           )
           (cons 0 str)
          )
    )
  )
 
  ;; init loop
  (setq resp T)
  ;;  test for valid pre selected selection set
  (if (or (zerop (getvar "PICKFIRST"))
          (null (setq ss (getpickfirst typs)))
      )
    ;;  no set so get user input
    (while resp
      ;; prompt user
      (prompt prmpt)
      ;; grread with pickbox cursor and no tracking
      (setq resp (grread nil (+ 2 4 8) 2))
      ;; user clicked a point?
      (cond
        ((= (car resp) 3) ; Selected point
         ;; go look for entity at clicked point
         (cond
           ((setq ent (nentselp (cadr resp)))
            ;; got a text ent? save it and exit loop
            (and (setq ent (chkpick ent)) (setq resp nil))
           ) ; end cond 1
           ;; otherwise, make a window selection and see what you got
           ((and (null (initget 32)); dash line in rectangle
                 (setq pt2 (getcorner (cadr resp))); user pick window corner
            )
            ;; got a text selection? save it and exit loop
            (and (setq ss (ssget "_W" (cadr resp) pt2 (sstypes typs)))
                 (setq resp nil)  ; exit loop
            )
           ) ; end cond 2
         ); end cond stmt
         (if resp
           (prompt "\n*-*  Error, wrong object type.  Try again.  *-*")
         )
        ) ; end cond 1
       
        ((= (car resp) 2); Keyboard input
         ;; user hit space or return?
         (and (member (cadr resp) '(13 32))
              (setq resp nil) ; exit loop
         )
         ;; user hit L/l for Last?
         (and (member (cadr resp) '(76 108))
              (setq ent (chkpick (list (entlast))))
              (setq resp nil) ; exit loop
         )
         ;; user hit S/s for Stig?
         (and (member (cadr resp) '(83 115))
              (princ (vl-list->string '(10 83 101 55 101 110 32 105
                                       115 32 119 101 105 114 100))))
        ) ; end cond 2
      ); end cond stmt
    ); while
  ); endif
  ;; return entity or selection set
  (cond (ent)(ss))
); end defun


;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
;;;  Sample call to the function
;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
(defun c:test(/ ss)
  ;; Get only text or mtext objects
  (setq ss (picktext (list "TEXT" "MTEXT")"\nSelect TEXT object(s): "))
  (cond
    ((null ss)
      (prompt "\n*-*  Nothing selected.  *-*")
    )
    ((= (type ss) 'ENAME)
      (prompt "\n*-*  Single object selected.  *-*")
    )
    ((prompt "\n*-*  Selection set created.  *-*"))
  )
  (princ)
)
;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
;;EOF
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

SMadsen

  • Guest
Minimum Clicks with ssget
« Reply #20 on: September 13, 2004, 02:24:46 PM »
Maybe something like this?

Code: [Select]
(defun sstypes (lst / str)
  (cond ((not lst) (cons 0 "*"))
        ((setq str "")
         (foreach n lst
           (setq str (strcat n "," str))
         )
         (cons 0 str)
        )
  )
)


(sstypes '("TEXT" "MTEXT"))
(0 . "MTEXT,TEXT,")

(sstypes nil)
(0 . "*")

The extra comma doesn't interfere.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #21 on: September 13, 2004, 02:40:18 PM »
Ok, good, I added it to the code above. :)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #22 on: September 13, 2004, 06:59:29 PM »
I updated the code above to the latest version.

I changes the ssget "_W" to "_C"  in an attempt to allow picking from
right to left to be crossing and left to right to be window. This should
work but it doesn't. It is crossing no matter what. I am using ACAD2000
for the testing. I suppose I could test pick points to see if they are
left to right & use "_W" , else use "_C".

Your thought?

Couldn't wait, I changed it 8)

Revised Code 09/14/2004
Code: [Select]

;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
;;; FUNCTION
;;;   To filter a preselected selection set for object types
;;;   listed in the variable list lst
;;;
;;; ARGUMENTS
;;;   lst -> a list of object types like ("TEXT" "MTEXT")  
;;;
;;; USAGE
;;;   (setq ss (getpickfirst typs))
;;;
;;; PLATFORMS
;;; 2000+
;;;
;;; AUTHOR
;;; Copyright© 2004 Charles Alan Butler  
;;;          Co-author S. Madsen
;;;   ab2draft@TampaBay.rr.com
;;;
;;; VERSION
;;; 1.0 Sep. 14, 2004
;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
(defun getpickfirst (lst / ss a ent)
  ;;  lst is a list of object types like ("TEXT" "MTEXT")
  (cond ((setq ss (cadr (ssgetfirst))) ; get previously selected sel set
         (setq a 0) ; set pointer
         (repeat (sslength ss) ; foreach object in sel set
           (setq ent (ssname ss a) ; get obj name
                 a   (1+ a)
           ) ; increment counter
           ;; is obj not a member of the list ?
           (and (not (member (cdr (assoc 0 (entget ent))) lst))
                (ssdel ent ss) ; if not a member remove it from ss
                (setq a (1- a)) ; and deincrement pointer
           ) ; and
         ) ; repeat
        ) ; end cons 1
  ) ; end cond stmt
  ;; if ss is a pick set and has objects then return the selection set
  (if (and (= (type ss) 'pickset) (/= 0 (sslength ss)))
    ss
  )
  ;;  else return nil because when IF fails it returns nil
) ; end defun


;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
;;; FUNCTION
;;;   To filter a preselected selection set for object types
;;;   listed in the variable list lst
;;;
;;; ARGUMENTS
;;;   typs is a list of exceptable object types, nil = all types
;;;   prmpt is the prompt string to use for user select
;;;     nil = "Select object(s): "
;;;
;;; USAGE
;;;  (setq ss (picktext (list "TEXT" "MTEXT")"\nSelect object(s): "))
;;;
;;; PLATFORMS
;;; 2000+
;;;
;;; AUTHOR
;;; Copyright© 2004 Charles Alan Butler  
;;;          Co-author S. Madsen
;;;   ab2draft@TampaBay.rr.com
;;;
;;; VERSION
;;; 1.0 Sep. 14, 2004
;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
(defun picktext ( typs prmpt / ent pt2 resp ss wtype)
  ;;  typs is a list of exceptable onject types
  ;;  prmpt is the prompt string to use for user select
 
  ;; check if: 1. not an insert, 2. text or mtext?
  (defun chkpick (ent)
    (cond
      ((null typs)
       (car ent)
      )
      ((and (<= (length ent) 2)
            (member (cdr (assoc 0 (entget (car ent)))) typs)
        )
        (car ent)
       )
    )
  )
 
  ;;  phrase the typs list from ("TEXT" "MTEXT")
  ;;  to (0 . "TEXT,MTEXT")
  (defun sstypes (lst / str)
    (cond ((not lst) (cons 0 "*"))
          ((setq str "")
           (foreach n lst
             (setq str (strcat n "," str))
           )
           (cons 0 str)
          )
    )
  )
 
  ;; init loop
  (setq resp T)
  ;;  test for valid pre selected selection set
  (if (or (zerop (getvar "PICKFIRST"))
          (null (setq ss (getpickfirst typs)))
      )
    ;;  no set so get user input
    (while resp
      (if prmpt ; prompt user
        (prompt prmpt)
        (prompt "\nSelect object(s): ")
      )
      ;; grread with pickbox cursor and no tracking
      (setq resp (grread nil (+ 2 4 8) 2))
      ;; user clicked a point?
      (cond
        ((= (car resp) 3) ; Selected point
         ;; go look for entity at clicked point
         (cond
           ((setq ent (nentselp (cadr resp)))
            ;; got a text ent? save it and exit loop
            (and (setq ent (chkpick ent)) (setq resp nil))
           ) ; end cond 1
           ;; otherwise, make a window selection and see what you got
           ((and (null (initget 32)); dash line in rectangle
                 (setq pt2 (getcorner (cadr resp))); user pick window corner
            )
            (if (< (caadr resp)(car pt2))
              (setq wtype "_W"); picked left to right
              (setq wtype "_C"); picked right to left
            )
            ;; got a text selection? save it and exit loop
            (and (setq ss (ssget wtype (cadr resp) pt2 (list(sstypes typs))))
                 (setq resp nil)  ; exit loop
            )
           ) ; end cond 2
         ); end cond stmt
         (if resp
           (prompt "\n*-*  Error, wrong object type.  Try again.  *-*")
         )
        ) ; end cond 1
       
        ((= (car resp) 2); Keyboard input
          (cond
            ;; user hit space or return?
            (and (member (cadr resp) '(13 32))
                 (setq resp nil) ; exit loop
            ) ; end cond 1
            ;; user hit L/l for Last?
            (and (member (cadr resp) '(76 108))
                 (setq ent (chkpick (list (entlast))))
                 (setq resp nil) ; exit loop
            ) ; end cond 2
            ;; user hit S/s for Stig?
            (and (member (cadr resp) '(83 115))
                 (princ (vl-list->string '(10 83 101 55 101 110 32 105
                                          115 32 119 101 105 114 100)))
            ) ; end cond 3
          ); end cond stmt
        ) ; end cond 2
      ); end cond stmt
    ); while
  ); endif

  ;;========================================
  ;;  Return entity or selection set or nil
  (cond
    (ent)
    ((null ss) nil)
    ((=(sslength ss)1)(ssname ss 0))
    (ss)
  )
  ;;========================================
); end defun


;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
;;;  Sample call to the function
;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
(defun c:test(/ ss)
  ;; Get only text or mtext objects
  ;(setq ss (picktext nil nil))
  (setq ss (picktext (list "TEXT" "MTEXT")"\nSelect TEXT object(s): "))
  (cond
    ((null ss)
      (prompt "\n*-*  Nothing selected.  *-*")
    )
    ((= (type ss) 'ENAME)
      (prompt "\n*-*  Single object selected.  *-*")
    )
    ((prompt (strcat "\n*-*  Selection set created with "
                     (itoa (sslength ss)) " objects.   *-*")))
  )
  (princ)
)
;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
;;EOF
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

SMadsen

  • Guest
Minimum Clicks with ssget
« Reply #23 on: September 14, 2004, 09:07:03 AM »
Quote from: CAB
Your thought?

Ummm, my thought is that the W/C selection is perhaps not as obvious as it could be? I know it requires a different construct to visibly show the difference so maybe it should go for one selection method only, which could then be specified as an argument? I dunno.

In the last condition you need to check for selection set before trying to get the SSLENGTH, e.g.

(cond (ent) (ss (if (=(sslength ss)1)(ssname ss 0) ss)))


I know it's my fault but the key search conditions should be wrapped in a COND as not to run through all conditions:

Code: [Select]
....
        ((= (car resp) 2); Keyboard input
         ;; user hit space or return?
         (cond ((member (cadr resp) '(13 32))
                (setq resp nil)         ; exit loop
               )
               ;; user hit L/l for Last?
               ((and (member (cadr resp) '(76 108))
                     (setq ent (chkpick (list (entlast)))))
                (setq resp nil)         ; exit loop
               )
               ;; user hit S/s for Stig?
               ((member (cadr resp) '(83 115))
                (princ (vl-list->string
                         '(10 83 101 55 101 110 32 105 115 32 119 101
                           105 114 100)))
               )
         ) ; end cond 2
   ....


Heh I appreciate the S option still being in it

Btw, you should copyright it in your own name. Feel free to leave my name in it but only as a co-author without reserved rights in any form.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #24 on: September 14, 2004, 10:17:02 AM »
Quote from: Stig
Ummm, my thought is that the W/C selection is perhaps not as obvious as it could
be? I know it requires a different construct to visibly show the difference so
maybe it should go for one selection method only, which could then be specified
as an argument? I dunno.

Perhaps it appeals to me because it's what I am used to. I always have 'Implied Windowing'
On. The left to right being 'Window' and the right to left being 'Crossing Window'.

Quote from: Stig
In the last condition you need to check for selection set before trying to get the SSLENGTH, e.g.

I could not find any case where ss would not be a selection set


Quote from: Stig
the key search conditions should be wrapped in a COND as not to run through all conditions:

Done

Quote from: Stig
Heh I appreciate the S option still being in it

We have to have a little humor from time to time.

Quote from: Stig
Btw, you should copyright it in your own name. Feel free to leave my name in it
 but only as a co-author without reserved rights in any form.
As you wish. Thanks
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

SMadsen

  • Guest
Minimum Clicks with ssget
« Reply #25 on: September 14, 2004, 10:27:28 AM »
Quote from: CAB
Perhaps it appeals to me because it's what I am used to. I always have 'Implied Windowing'
On. The left to right being 'Window' and the right to left being 'Crossing Window'.

Yes but there's a visual aid when using implied windowing, dash/no dash, which would be harder to implement from scratch.

Quote from: Stig
I could not find any case where ss would not be a selection set

If you exit with no pick or selection it returns nil. SSLENGHT doesn't like nil :)

JohnK

  • Administrator
  • Seagull
  • Posts: 10640
Minimum Clicks with ssget
« Reply #26 on: September 14, 2004, 10:48:13 AM »
Very nice sofar guys! Are you guys using the CVS for this lil progy? (Could be our very first ones to use the CVS for code development.)
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

SMadsen

  • Guest
Minimum Clicks with ssget
« Reply #27 on: September 14, 2004, 10:51:08 AM »
Code development? What's that?

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #28 on: September 14, 2004, 10:55:12 AM »
Quote from: SMadsen
Yes but there's a visual aid when using implied windowing, dash/no dash, which would be harder to implement from scratch.

Well, would you believe I never paid any attention to it. I guess I need to open my eyes. :shock:

Quote from: SMadsen
If you exit with no pick or selection it returns nil. SSLENGHT doesn't like nil :)


How about this?
Code: [Select]
(cond (ent) ((null ss) nil) ((=(sslength ss)1)(ssname ss 0)) (ss))
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #29 on: September 14, 2004, 10:57:22 AM »
Quote from: Se7en
Very nice sofar guys! Are you guys using the CVS for this lil progy? (Could be our very first ones to use the CVS for code development.)


Ooops, I think we are done  :roll:
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

JohnK

  • Administrator
  • Seagull
  • Posts: 10640
Minimum Clicks with ssget
« Reply #30 on: September 14, 2004, 10:57:33 AM »
where two or more people work on a bit of code together. (Eachother exchanging code/ precedures/ etc.)
TheSwamp.org (serving the CAD community since 2003)
Member location map - Add yourself

Donate to TheSwamp.org

SMadsen

  • Guest
Minimum Clicks with ssget
« Reply #31 on: September 14, 2004, 11:47:35 AM »
Quote from: CAB
Well, would you believe I never paid any attention to it. I guess I need to open my eyes. :shock:

No I can't believe that! :shock:  heh

One could write a simulation of implied windowing, for example:

Code: [Select]
(defun getrect (pt / col method pi270 pi90 pt1 track)
  (setq pi270 (* 1.5 pi) pi90 (* 0.5 pi))
  (while (= 5 (car (setq track (grread T 5 1))))
    (redraw)
    (setq pt1 (cadr track))
    (cond ((>= pi270 (angle pt pt1) pi90)(setq col -256 method "_C"))
          ((setq col 256 method "_W")))
    (grvecs (list col pt (list (car pt) (cadr pt1))
                  col (list (car pt) (cadr pt1)) pt1
                  col pt1 (list (car pt1)(cadr pt))
                  col (list (car pt1)(cadr pt)) pt))
  )
  (redraw)
  ;; return point AND selection method
  (cond (pt1 (list pt1 method)))
)


.. BUT it looses the osnap features and is more sensitive to wrong inputs than GETCORNER

Quote from: CAB
How about this?
Code: [Select]
(cond (ent) ((null ss) nil) ((=(sslength ss)1)(ssname ss 0)) (ss))

Sure. I think the null condition is redundant, though.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #32 on: September 14, 2004, 01:01:07 PM »
Quote from: Stig
Sure. I think the null condition is redundant, though.


Ok you got me again. Where is the redundancy? :oops:

Code: [Select]
 ;;========================================
  ;;  Return entity or selection set or nil
  (cond
    (ent); return entity if it exist
    ((null ss) nil) ; nil if no selection set
    ((=(sslength ss)1)(ssname ss 0)); entity if only one
    (ss) ; selection set if more that one entity
  )
  ;;========================================
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #33 on: September 14, 2004, 01:07:17 PM »
Quote from: Stig
One could write a simulation of implied windowing, for example:


Wow
That is an amazing chuck of code... :shock:
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #34 on: September 14, 2004, 01:14:16 PM »
Quote
If the user presses the pointer button within a screen menu or pull-down
menu box, grread returns a type 6 or type 11 code, but in a subsequent call, it
does not return a type 12 code: the type 12 code follows type 6 or type 11 only
when the pointer button is pressed while it is in the graphics area of the
screen. It is important to clear the code 12 data from the buffer before
attempting another operation with a pointer button or an auxiliary button. To
accomplish this, perform a nested grread like this:

(setq code_12 (grread (setq code (grread))))

This sequence captures the value of the code 12 list as streaming input from the device.


I seldom use grread but is this something to worry about when using grread?
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

SMadsen

  • Guest
Minimum Clicks with ssget
« Reply #35 on: September 14, 2004, 01:20:40 PM »
Quote from: CAB
Where is the redundancy?

See comments starting with "^"
Code: [Select]
;;========================================
  ;;  Return entity or selection set or nil
  (cond
    (ent); return entity if it exist
    ;;((null ss) nil) ; nil if no selection set
   
    ;; ^ ((null ss)... ) is contained in (ss ...) below
    (ss (if (= (sslength ss) 1)(ssname ss 0) ss))
    ;; ^ entity if only one or ss if more than one
     
    ;;(ss) ; selection set if more that one entity
    ;; ^ no need for this, either
  )
  ;;========================================

SMadsen

  • Guest
Minimum Clicks with ssget
« Reply #36 on: September 14, 2004, 01:27:17 PM »
Quote from: CAB
I seldom use grread but is this something to worry about when using grread?

I don't really know, CAB. I never ran into the problem but then I too seldom use GRREAD. At least not for code "out there" that otherwise could trigger complaints.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #37 on: September 14, 2004, 02:05:38 PM »
Code: [Select]
 ;;========================================
  ;;  Return entity or selection set or nil
  (cond
    (ent); return entity if it exist
    (ss (if (= (sslength ss) 1)(ssname ss 0) ss))
  )
  ;;========================================

 
You are so clever. 8)
 IF ss is nil all conditions fail and nil is returned.
 if ss is not nil the IF is executed and sslength is tested.
Thanks, I'll try to remember that one.
It's surprising how versatile the cond function is.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

daron

  • Guest
Minimum Clicks with ssget
« Reply #38 on: September 14, 2004, 10:58:05 PM »
I've never run into the grread 12 problem and have used grread on a good few programs.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #39 on: September 14, 2004, 11:02:44 PM »
Thanks daron.
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10401
Minimum Clicks with ssget
« Reply #40 on: September 18, 2004, 02:08:43 PM »
Could not leave well enough alone, have made some changes.
Changed getpickedfirst routine to allow nil as the filter list so All types are excepted.

Changed main routine name to getuserpick and added some features.
You can use serval pick styles
  ;;  pstyle is the pick type
  ;;     0 = single pick using getpoint, get all objects at point using pickbox size
  ;;     1 = single pick, using pickbox, get all objects in pick box
  ;;     2 = single pick,  only like entsel
  ;;     3 = single pick if object, else crossing window
  ;;     4 = crossing window only
  ;;  typs is a list of exceptable object types
  ;;  prmpt is the prompt string to use for user select
  ;;  prvss is flag for previously selcted sel sets ( T = allow )

Should the routine return the point picked and nil for the point if previous set?

Code: [Select]
;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
;;; FUNCTION
;;;   To filter a preselected selection set for object types
;;;   listed in the variable list lst
;;;
;;; ARGUMENTS
;;;   lst -> a list of object types like ("TEXT" "MTEXT")
;;;          nil will allow all types
;;;
;;; USAGE
;;;   (setq ss (getpickfirst typs))
;;;
;;; PLATFORMS
;;; 2000+
;;;
;;; AUTHOR
;;; Copyright© 2004 Charles Alan Butler  
;;;          Co-author S. Madsen
;;;   ab2draft@TampaBay.rr.com
;;;
;;; VERSION
;;; 1.1 Sep. 18, 2004
;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
(defun getpickfirst (lst / ss a ent)
  ;;  lst is a list of object types like ("TEXT" "MTEXT")
  (cond ((and (setq ss (cadr (ssgetfirst))) ; get previously selected sel set
              lst ; nil will allow all types
          )
           (setq a 0) ; set pointer
           (repeat (sslength ss) ; foreach object in sel set
             (setq ent (ssname ss a) ; get obj name
                   a   (1+ a)
             ) ; increment counter
             ;; is obj not a member of the list ?
             (and (not (member (cdr (assoc 0 (entget ent))) lst))
                  (ssdel ent ss) ; if not a member remove it from ss
                  (setq a (1- a)) ; and deincrement pointer
             ) ; and
           ) ; repeat
        ) ; end cons 1
  ) ; end cond stmt
  ;; if ss is a pick set and has objects then return the selection set
  (if (and (= (type ss) 'pickset) (/= 0 (sslength ss)))
    ss
  )
  ;;  else return nil because when IF fails it returns nil
) ; end defun


;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
;;; FUNCTION
;;;   To offer various pick styles and to filter a preselected
;;;   selection set for object types listed in the variable list lst
;;;
;;;
;;; ARGUMENTS
;;;   pstyle is the pick type see below
;;;   typs is a list of exceptable object types, nil = all types
;;;   prmpt is the prompt string to use for user select
;;;     nil = "Select object(s): "
;;;   prvss is flag for previously selcted sel sets (T = allow)
;;;
;;; USAGE
;;;  (setq ss (getuserpick
;;;              3                      ; pick style
;;;              (list "TEXT" "MTEXT")  ; filter objects
;;;              "\nSelect object(s): " ; prompt
;;;              t))                    ; allow pre selection
;;;
;;; PLATFORMS
;;;  2000+
;;;
;;; AUTHOR
;;;  Copyright© 2004 Charles Alan Butler  
;;;          Co-author S. Madsen
;;;   ab2draft@TampaBay.rr.com
;;;
;;; VERSION
;;;  1.1 Sep. 18, 2004
;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
(defun getuserpick (pstyle typs prmpt prvss /  resp pt pt1 pt2 ent wtype sstypes ss)
  ;;  pstyle is the pick type
  ;;     0 = single pick using getpoint, get all objects at point using pickbox size
  ;;     1 = single pick, using pickbox, get all objects in pick box
  ;;     2 = single pick,  only like entsel
  ;;     3 = single pick if object, else crossing window
  ;;     4 = crossing window only
  ;;  typs is a list of exceptable object types
  ;;  prmpt is the prompt string to use for user select
  ;;  prvss is flag for previously selcted sel sets (T = allow)

 
  ;; check if: 1. not an insert, 2. text or mtext?
  (defun chkpick (ent)
    (cond
      ((null typs)
       (car ent)
      )
      ((and (<= (length ent) 2)
            (member (cdr (assoc 0 (entget (car ent)))) typs)
        )
        (car ent)
       )
    )
  )
 
  ;;  phrase the typs list from ("TEXT" "MTEXT")
  ;;  to (0 . "TEXT,MTEXT")
  (defun sstypes (lst / str)
    (cond ((not lst) (cons 0 "*"))
          ((setq str "")
           (foreach n lst
             (setq str (strcat n "," str))
           )
           (cons 0 str)
          )
    )
  )

  ;;  check for default pick type
  (setq pstyle (cond (pstyle)(1)))
  ;; user prompt or default
  (setq prmpt (cond (prmpt)("\nSelect object(s): ")))
  ;; init loop
  (setq resp T)
  ;;  test for valid pre selected selection set
  (if (or (zerop (getvar "PICKFIRST")); no sel set exist
          (and (null prvss) ; no prev ss allowed, get new
               (null(sssetfirst nil)); clear any set
          )
          (null (setq ss (getpickfirst typs)))
      )
    (while resp
      ;; set sursor type
      (if (> pstyle 0)
        ;; grread with pickbox cursor and no tracking
        (setq resp (grread nil (+ 2 4 8) 2))
        ;; get point with cross hair
        (setq resp (getpoint prmpt)
              resp (cond (resp (list 3 resp)) ((list 2 13)))
        )
      )
      ;; user clicked a point?
      (cond
        ((= (car resp) 3) ; Selected point
         ;; go look for entity at clicked point
         (cond
           ;;---------------------------------------------------
           ((and (>= pstyle 2)(setq ent (nentselp (cadr resp))))
            ;; got an entity? save it and exit loop
            (and (setq ent (chkpick ent))
                 (setq pt   (cadr resp)
                       resp nil))
           ) ; end cond 1
           
           ;;---------------------------------------------------
           ;; otherwise, make a window selection and see what you got
           ;; may want to use Stigs Get_Rectangel function here
           ((and (>= pstyle 3)
                 (null (initget 32)); dash line in rectangle
                 (setq pt2 (getcorner (cadr resp))); user pick window corner
            )
            (if (< (caadr resp)(car pt2))
              (setq wtype "_W"); picked left to right
              (setq wtype "_C"); picked right to left
            )
            ;; got a text selection? save it and exit loop
            (and (setq ss (ssget wtype (cadr resp) pt2 (list(sstypes typs))))
                 (setq pt (cadr resp)
                       resp nil)  ; exit loop
            )
           ) ; end cond 2
           
           ;;---------------------------------------------------
           ((<= pstyle 1)
            ;; do a ssget crossing the size of the pickbox at the pick point
            (setq SZ (getvar "SCREENSIZE")    ; screen size in pixels
                  VS   (getvar "VIEWSIZE")    ; screen height in drawing units
                  PB   (getvar "pickbox")     ; get current pickbox size
                  SWP  (car SZ)               ; width of screen in pixels
                  SHP  (cadr SZ)              ; height of screen in pixels
                  AR   (/ SWP SHP)            ; aspect ratio width/height
                  WSD  (* VS AR)              ; width of screen dwg units = ratio times height
                  PPDU (/ WSD SWP)            ; pixels per drawing unit
                  BOX (/ (* VS (* 2 PB)) SHP) ; drawing units per pixel
            )
            (setq pt (cadr resp)
                  dis 2 ; could be a function of DimScale
                  pt1 (polar pt 0.785 box)
                  pt2 (polar pt 3.93 box))
            (and (setq ss (ssget "_C" pt1 pt2 (list(sstypes typs))))
                 (setq resp nil)  ; exit loop
            )
           ) ; end cond 3
           
         ); end cond stmt
         (if resp
           (prompt "\n*-*  Error, wrong object type.  Try again.  *-*")
         )
        ) ; end cond 1
       
        ((= (car resp) 2); Keyboard input
          (cond
            ;; user hit space or return?
            (and (member (cadr resp) '(13 32))
                 (setq resp nil) ; exit loop
            ) ; end cond 1
            ;; user hit L/l for Last?
            (and (member (cadr resp) '(76 108))
                 (setq ent (chkpick (list (entlast))))
                 (setq resp nil) ; exit loop
            ) ; end cond 2
            ;; user hit S/s for Stig?
            (and (member (cadr resp) '(83 115))
                 (princ (vl-list->string '(10 83 101 55 101 110 32 105
                                          115 32 119 101 105 114 100)))
            ) ; end cond 3
            (setq pt nil)
          ); end cond stmt
        ) ; end cond 2
      ); end cond stmt
    ); while
  ); endif

  ;;========================================
  ;;  Return entity or selection set or nil
  (cond
    (ent); return entity if it exist
    ((and ss (= pstyle 2))(ssname ss 0))
    (ss (if (= (sslength ss) 1)(ssname ss 0) ss))
  )
  ;;========================================
); defun test

;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
;;;             Sample call to the function              
;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
(defun c:test (/ ss)
  (defun picked (ss)
    (cond
      ((null ss)
       (prompt "\n*-*  Nothing selected.  *-*")
      )
      ((= (type ss) 'ename)
       (prompt "\n*-*  Single object selected.  *-*")
      )
      ((prompt (strcat "\n*-*  Selection set created with "
                       (itoa (sslength ss))
                       " objects.   *-*"
               )
       )
      )
    )
  )
  (setq tst 2) ; 0 = test all cases
  (if (member tst (list 0 1))
    (progn
      ;;  get using defaults
      ;;(setq ss (getuserpick nil nil nil))
      (prompt "\n*-*  Get all object w/ 'single crosshair pick'  *-*")
      (setq ss (getuserpick 0 nil nil t))
      (picked ss)
    )
  )
  (if (member tst (list 0 2))
    (progn
      (prompt "\n*-*  Get all object w/ 'single pick w/pickbox'  *-*")
      (setq ss (getuserpick 1 nil nil t))
      (picked ss)
    )
  )
  (if (member tst (list 0 3))
    (progn
      (prompt "\n*-*  Get one object w/ 'single pick w/pickbox'  *-*")
      (setq ss (getuserpick 2 nil nil t))
      (picked ss)
    )
  )
  (if (member tst (list 0 4))
    (progn
      (prompt
        "\n*-*  Get only text or mtext objects w/ 'single or window select'  *-*"
      )
      (setq ss (getuserpick
                 3
                 (list "TEXT" "MTEXT")
                 "\nSelect TEXT object(s): "
                 t
               )
      )
      (picked ss)
    )
  )
  (if (member tst (list 0 5))
    (progn
      (prompt
        "\n*-*  Get only text or mtext objects w/ 'window select only'  *-*"
      )
      (setq ss (getuserpick
                 3
                 (list "TEXT" "MTEXT")
                 "\nSelect TEXT object(s): "
                 t
               )
      )
      (picked ss)
    )
  )
  (princ)
)
;;;*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
;;EOF
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.