getkword alias function?

Discussion in 'AutoCAD' started by David Kozina, Apr 6, 2004.

  1. David Kozina

    David Kozina Guest

    Often, when I use the getkword function, when I provide the user with a list
    of keyword options, what I usually *really* end up doing with the user's
    response is setting a variable to some value - via some (cond...) statement
    of varying length, depending on the input of the moment and then going from
    there.

    Example:

    ; initialize layer...
    (setq message "Draw: (Wall/Column/Opening/Hatching)?")
    (initget "Wall Column Opening Hatching")
    (setq ObjectType_str
    (getkword message)
    )
    (setq LayerName_str
    (cond
    ((eq ObjectType_str "Wall") "S-WALL")
    ((eq ObjectType_str "Column") "S-COLS")
    ((eq ObjectType_str "Opening") "S-OPEN")
    ((eq ObjectType_str "Hatching") "S-PATT")
    )
    )
    ; create/set layer
    ; ...now do more stuff


    Does this look/sound familiar?

    Now the getkword function I actually use is wrapped up a bit more, based on
    code found in the book Maximizing AutoCAD, in the sense that it provides for
    current and preset default options, which makes it much more user friendly.
    I'd post it, but since it isn't my code (and was commercially published at
    that), I don't feel I have the right to do so.

    Now, the above is straightforward enough, I suppose - but...
    I was wondering if any of you have found it useful to deal with the above
    scenario by 'wrapping things up' yet another time, with the idea that user
    selects Option X, but the value returned is 'what you really want', IOW,
    'Alias X'.

    My thoughts on how to accomplish this would be to provide a list of dotted
    pairs, perhaps... like so in the above scenario: '(("Wall" .
    "S-WALL")("Column" . "S-COLS")("Opening" . "S-OPEN")("Hatching" .
    "S-PATT")) - and a brief message string (without the options, in this case,
    "Draw:"), whereupon the "real" command line message could be constructed
    from the (car's of the input list, as well as a constructed initget string,
    in the same manner.
    Current and default options could be provided as well, (or if none provided,
    a default based on the first member of the input list)

    The returned result would be the cdr of the assoc of the input list... *or*
    would it be more useful to return the assoc dotted pair itself - perhaps for
    further testing/branching?

    Seems that this 'keyword alias' result would abbreviate things quite a bit
    in many cases, especially with respects to the complete bypass of the
    following cond statement, no?

    I've already created my own version of this, btw, and it seems to work
    okay... but, I'm wondering you see that I am overlooking something important
    in the entire picture? Arbitrary input? (I haven't used this particular
    get* aspect much, I admit.) What about other types of 'alias returns'? For
    instance, in this particular case I'm thinking of returning an alias string
    or even a list of strings, but what about actually running an 'alias
    subroutine' or 'alias function' based on the keyword selected?

    Is this idea Good, Bad or Ugly? :)

    Most appreciative of any input.

    Best regards,
    David Kozina
     
    David Kozina, Apr 6, 2004
    #1
  2. David,
    That is a great idea and falls under the general category of collecting good subroutines. You always want to slick your
    subs out like what you are saying as long as you keep them general enough to use for all your routines. No news there.
    I wanted to post some code that was derived from a thread a while back. We were trying to make a routine that would let
    you pick text or type it to get a value. It involves the grread function and was very tricky. It is one of the best
    subroutines I have though and is so cool because I can use it anywhere to make text input easier.
    Take a look, it is not what you asked for but has enough code to show how to catch user input with grread and process
    it.
    the EXTRACT_NUM_STR function is not included, anyone that can do this can easily write ther own function to grab a
    number from a cluttered string.

    ;------GET NUMBER OR U (UNDO) FROM USER BY TEXT OR TYPING-------
    ;(GET-NUM-TXT-TYPE-D "pick a number or type it <123.5>:" 123.5)

    (DEFUN GET-NUM-TXT-TYPE-D (MSG DEFAULT / NUM NUM-VAL NUM-REST SRC-TEXT STOP)
    (WHILE (NOT STOP)
    (PRINC MSG)
    (SETQ NUM (vl-catch-all-apply 'grread '(NIL 14 2)))
    (COND
    ;ESC
    ((OR (vl-catch-all-error-p NUM)
    (EQUAL NUM '(25 229))
    )
    (SETQ NUM-VAL NIL
    STOP 1
    )
    )
    ;TOOLBAR PICK
    ((EQUAL (CAR NUM) 11)
    (SETQ STOP NIL)
    )
    ;ENTER
    ((OR (EQUAL NUM '(2 13))
    (EQUAL NUM '(2 32))
    )
    (SETQ NUM-VAL DEFAULT
    STOP 1
    )
    )
    ;LETTER
    ((AND (= (CAR NUM) 2)
    (WCMATCH (STRCASE (CHR (CADR NUM))) "@")
    )
    (SETQ NUM-VAL (STRCASE (CHR (CADR NUM)))
    STOP 1
    )
    )
    ;NUMBER
    ((AND (= (CAR NUM) 2)
    (WCMATCH (CHR (CADR NUM)) "1,2,3,4,5,6,7,8,9,0,`.")
    )
    (prompt (setq NUM (chr(cadr NUM))))
    ;KEEP ASKING FOR NUMBER AND FILTER WHILE AT IT
    (while (and (= 2 (car(setq in (grread))))(AND (/= 13 (cadr in))(/= 32 (cadr in))))
    (setq in (chr(cadr in)))
    (cond ((= in (chr 08)) ;backspace
    (if (/= "" NUM)
    (setq NUM (substr NUM 1 (1- (strlen NUM))))
    )
    (princ "\n")(prompt NUM)
    )
    ( (member in '("0" "1" "2" "3" "4" "5" "6" "7" "8" "9" "."))
    (setq NUM (strcat NUM in))
    (prompt in)
    )
    )
    )
    (setq NUM-VAL (DISTOF NUM 2)
    STOP 1
    )
    )
    ;IF ITS A POINT, SELECT TEXT
    ((AND (= (CAR NUM) 3)
    (SETQ NUM (NENTSELP (CADR NUM))) ;(NENTSELP (GETPOINT))
    (SETQ NUM (CAR NUM))
    )
    ;GET TEXT VALUE AND TEST FOR NUMBER
    (IF (OR (= (cdr (assoc 0 (entget NUM))) "ATTRIB")
    (= (cdr (assoc 0 (entget NUM))) "TEXT")
    (= (cdr (assoc 0 (entget NUM))) "MTEXT")
    )
    (PROGN
    (REDRAW NUM 3)
    (SETQ SRC-TEXT (CDR (ASSOC 1 (ENTGET NUM))))
    ;CLEAN OUT MTEXT FORMATS IF MTEXT
    (IF (AND (= (CDR (ASSOC 0 (ENTGET NUM))) "MTEXT")
    (WCMATCH SRC-TEXT "*;*")
    )
    (SETQ SRC-TEXT (SUBSTR SRC-TEXT (+ 1 (VL-STRING-SEARCH ";" SRC-TEXT))))
    )
    ;EXTRACT NUMBER
    (SETQ NUM-VAL (DISTOF (CT-REMOVE-CHARS (CADR (EXTRACT_NUM_STR SRC-TEXT))) 2)
    STOP 1
    )
    )
    (PRINC "\nThat was not a kind of text.")
    )
    )
    (1
    (SETQ NUM-VAL NIL
    STOP 1
    )
    )
    )
    )
    NUM-VAL
    )

    "David Kozina" <>
    |>Often, when I use the getkword function, when I provide the user with a list
    |>of keyword options, what I usually *really* end up doing with the user's
    |>response is setting a variable to some value - via some (cond...) statement
    |>of varying length, depending on the input of the moment and then going from
    |>there.
    |>
    |>Example:
    |>
    |>; initialize layer...
    |>(setq message "Draw: (Wall/Column/Opening/Hatching)?")
    |>(initget "Wall Column Opening Hatching")
    |>(setq ObjectType_str
    |> (getkword message)
    |>)
    |>(setq LayerName_str
    |> (cond
    |> ((eq ObjectType_str "Wall") "S-WALL")
    |> ((eq ObjectType_str "Column") "S-COLS")
    |> ((eq ObjectType_str "Opening") "S-OPEN")
    |> ((eq ObjectType_str "Hatching") "S-PATT")
    |> )
    |>)
    |>; create/set layer
    |>; ...now do more stuff
    |>
    ....
    James Maeding
    Civil Engineer/Programmer
     
    James Maeding, Apr 6, 2004
    #2
  3. David Kozina

    David Kozina Guest

    Thanks for the comments, James.

    I haven't used grread much, if any,
    to date - so I appreciate the example.

    Best regards,
    David Kozina
     
    David Kozina, Apr 7, 2004
    #3
  4. Hi David,

    As you are investigating grread, you may find this snip,
    which I posted in Oct, 2002, that uses grread to get key
    strokes from the user, echoing back * when they are actual
    keys, as sopposed to navigation keys etc.

    I've never used it myself, so I don't know how robust it is.
    It was a quick one off for someone looking how do do it ...

    (defun GetKeysMasked ( / Done Data Code Result )
    (while (not Done)
    (if (eq 2 (car (setq Data (grread t 8 1))))
    (cond
    ( (eq 39 (setq Code (cadr Data))) ; bogus, Fn keys etc
    (while /= 12 (cadr (setq Data (grread t 8 1)))) ; clear buffer
    )
    ( (< 31 Code 255) ; a key was pressed
    (setq Result (cons Code Result)) ; grab it
    (princ "*") ; echo * to command line
    )
    ( (eq 13 Code) (setq Done t)) ; done
    )
    )
    )
    (if Result (apply 'strcat (mapcar 'chr (reverse Result))))
    )

    If it doesn't contribute to your quest just 86 it :)

    Cheers,

    Michael.
     
    michael puckett, Apr 7, 2004
    #4
  5. David Kozina

    David Kozina Guest

    Seems to me that that routine would have some prank value...

    "So what do you type to run that routine?"
    "***"
    "Doesn't seem to work for me - are you sure that's right, Bubba?"
    "That's what it says..."

    Thanks, Michael.
     
    David Kozina, Apr 7, 2004
    #5
  6. David Kozina

    David Kozina Guest

    I can see I've hit a real hot topic here... :-/

    One question more on this subject, for any of you who may have created some
    additional tools for wrapping, or otherwise 'user-friendlifying' the (get*
    input functions.

    Assuming you feed your functions a set of arguments, such as
    (MyGetInput message current default [...])

    Have you also found it helpful to include an initget value in the argument
    list? IOW, do you prefer to handle the initget INSIDE the routine, or
    OUTSIDE, before running it? Any particular reasons why, one way or the
    other?

    Just curious... thanks for sharing your ideas on this.
     
    David Kozina, Apr 7, 2004
    #6
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.