Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Using arrow keys, Sending input without enter, and returning to last cmd

7 REPLIES 7
Reply
Message 1 of 8
Anonymous
1009 Views, 7 Replies

Using arrow keys, Sending input without enter, and returning to last cmd

In case if the title was too vague, I'm looking for a method to directly input a character WITHOUT hitting enter.

For example, Let's say I had a function that asks "press [a] to (do something), [b] to (do something else), [c] to ...".

Currently, I'm using "getkword" to do so, but getkword requires you to always press enter (or space) at the end before sending the input.

However, a lot of well-made programs (ex leemac), they can instantly execute to the next line as soon as you press the key. Sadly, I was also not experienced enough to understand what those people did... so I would appreciate if anyone could give me an idea of how to set it up.

Here's the small part of the program that I need such method:

(defun Menu (/ funcMod )
  (initget 1 "R I F S")
  (setq funcMod
    (cond
      (setq kwd
        (getkword
	  (strcat "\nWhich action would you like to do?"
		  "\n[R]eplace existing label,"
		  " [I]ncrement labels,"
		  " [F]ind identical blocks"
		  " [S]etup string schedule"
	  ); strcat
	); getkword
      ) (funcMod)
    ); cond
  ); setq
  (cond
    ( (= funcMod "R") (Replace) )
    ( (= funcMod "I") (Increment) )
    ( (= funcMod "F") (FindAll) )
    ( (= funcMod "S") (Setup) )
  )
)

 

 

Second question I wanna ask is a way to recognize special key (arrow keys in this case). I heard "grread" is the only way to do it. However, again, I'm not experienced enough to understand the instruction given:

http://docs.autodesk.com/ACD/2011/ENU/filesALR/WS1a9193826455f5ff1a32d8d10ebc6b7ccc-69ed.htm

Here's another part of the program that requires such method:

(defun Replace(/ term txt entName entType entInfo)
  ; initialize
  (ask-int '*pnlCur "Enter current panel number" *pnlLim)
  (ask-int '*strCur "Enter current string number" *strLim)

  (setq term 0)
  (while (= term 0)
    ; ask user for the label to modify
    (while (and (/= "TEXT" entType) (/= "MTEXT" entType) )
      (setq entName (car (entsel "\nSelect the label: ") ) )
      (cond
		(entName (setq entType (cdr (assoc 0 (entget entName) ) ) ) )
		(T (princ "No objects selected") )
		; read selected entity's type if present; otherwise repeat
      ); cond
    );while
    (setq entType 0)

    ; replace the chosen label
    (setq entInfo (entget entName) )
    (setq txt (strcat (itoa *pnlCur) "." (itoa *strCur) ) )
    (setq entInfo (subst (cons 1 txt) (assoc 1 entInfo) entInfo) )
    (entmod entInfo)
    (princ txt)
    (incrementBy 1)
  ); while
  (princ "\nEnd of the program.")
  (princ)
)

("ask-int" and "incrementBy" are defined functions. "ask-int" parse integar value to the named variable, and "incrementBy" increase *pnlCur and *strCur accordingly.)

While the program is waiting for an object to be selected, I wanted to add an option of using up / down key to (incrementBy 1) / (incrementBy -1).

 

 

For the last question, I believe it's closely related to reactor. Somewhat similar to the question above (but not solved by the same algorithm), I wanted to use ESC key to return to the one level above.

Since I only have 2 levels for now (menu and all other functions, excluding supporting functions like "ask-int"), it is basically reutnring to the menu. For this reason, I could probably modify "*error*" function with additional variable indicating last command, but I always prefer to program so that I can use it later. 

If anyone has extensive knowledge about reactor, please assist.

 

Thank you in advance 🙂

 

7 REPLIES 7
Message 2 of 8
scot-65
in reply to: Anonymous

For your first question a DCL dialog would be in order.

Have radio buttons as the choices with each having

in the action_tile area a call to the (done_dialog #)

where # is a number that can be compared in the

main part of your program, inside a COND [similar

to what you show].

 

Hints [linear as shown]:

 

;find and load dialog file here

 

(set_tile "Rad100" "Rad101") ;this is a "container" tile. :radio_row or :radio_column tile here :boxed_ if needed. key="Rad100";

...

(action_tile "Rad101" "(done_dialog 1)") ;this is a :radio_button who's case-sensitive key is "Rad101";

(action_tile "Rad102" "(done_dialog 2)")

...

(action_tile "accept" "(done_dialog 1)")

(action_tile "cancel" "(done_dialog 0)")

 

(setq sd (start_dialog)) ;done_dialog reports it's value to this start_dialog, so we need to fetch it for our use

 

;dialog closes at this point - unload it here

 

;Main Program

(if (and sd (> sd 0))

 (cond

  ( (= sd 1) ...)

  ...

 );cond

);if

 


Scot-65
A gift of extraordinary Common Sense does not require an Acronym Suffix to be added to my given name.


Message 3 of 8
stevor
in reply to: Anonymous

For whatever you want the arrow keys for,

you probably can achieve with Scott's DCL methods.

 

And the spacebar usually effects an 'enter,

and is close to all the keys.

 

There are examples of the Grread access to the keyboard,

but it requires constant evaluation of the reads,

like in a 'While loop.

 

S
Message 4 of 8
Kent1Cooper
in reply to: Anonymous


@Anonymous wrote:

.... Let's say I had a function that asks "press [a] to (do something), [b] to (do something else), [c] to ...".

Currently, I'm using "getkword" to do so, but getkword requires you to always press enter (or space) at the end before sending the input.

However, a lot of well-made programs (ex leemac), they can instantly execute to the next line as soon as you press the key. ....

.... 


For that part, here's one way:

 

(defun Menu (/ opt done)
  (prompt
    (strcat "\nWhich action would you like to do?"
      "\n[R]eplace existing label,"
      " [I]ncrement labels,"
      " [F]ind identical blocks"
      " [S]etup string schedule: "
    ); strcat
  ); prompt
  (while (and (not done) (setq opt (grread T 12 0)))
    (cond
      ((or (equal opt '(2 82)) (equal opt '(2 114))); typed R or r
        (setq done T); [stops (while) loop to end this routine with calling of chosen routine]
        (Replace)
      ); R condition
      ((or (equal opt '(2 73)) (equal opt '(2 105))); typed I or i
        (setq done T)
        (Increment)
      ); I condition
      ((or (equal opt '(2 70)) (equal opt '(2 102))); typed F or f
        (setq done T)
        (FindAll)
      ); F condition
      ((or (equal opt '(2 83)) (equal opt '(2 115))); typed S or s
        (setq done T)
        (Setup)
      ); S condition
    ); cond
  ); while
); defun

 

Be aware that one drawback of this approach for broader application is that it cannot accommodate multiple-letter option abbreviations, such as many AutoCAD commands have for options that start with the same letter, such as in -Layer: ON vs. OFF, Ltype vs. LWeight vs. LOck, TRansparency vs. Thaw, and Make vs. MATerial.  Whenever you may need that kind of distinction, I don't think there's any choice but to use (initget)/(getkword) and require the Enter/space to register the option abbreviation.

Kent Cooper, AIA
Message 5 of 8
Anonymous
in reply to: Kent1Cooper

Can you tell me where I can find the list of letters that I can use? I'm referring to the list with two elements that you're using to compare opt variable.

Message 6 of 8
Kent1Cooper
in reply to: Anonymous


@Anonymous wrote:

Can you tell me where I can find the list of letters that I can use? I'm referring to the list with two elements that you're using to compare opt variable.


The 82, 114, 73, 105, etc. are ASCII character numbers.  [The 2 before them is the indication in what (grread) returns that it's keyboard input.  The (grread) function could well work with different or maybe even no arguments -- I just copied it with the ...T 12 0... from something else.]

 

You can find a listing of ASCII character numbers in various places, but if you have a specific character in mind, use the (ascii) function to find its character number.  If you want an option triggered by Z [upper- or lower-case], do this:

 

Command: (ascii "Z")
90

Command: (ascii "z")
122

 

and put the resulting 90 and 122 in the (equal) functions:

 

...(equal opt '(2 90))...

 

etc.  And it doesn't need to be the first letter of the function you want it to trigger, nor does it even need to be a letter -- you can do the same with numbers and/or punctuation characters, in which case you would not check in an (or) function for two possible characters.  If you want & to trigger a function called (this&that), check for &'s ASCII number:

 

Command: (ascii "&")

38

 

then:

....

    (cond

....
      ((equal opt '(2 38)); typed & ; not in (or) with two tests
        (setq done T)
        (this&that)
      ); & condition

....

 

You can do a similar no-(or) one-ASCII-number approach if you want to use a letter but make it case-sensitive.  That way, you could, for example, have M trigger one function and m trigger a different one.

Kent Cooper, AIA
Message 7 of 8
Kent1Cooper
in reply to: Anonymous


@Anonymous wrote:

....

While the program is waiting for an object to be selected, I wanted to add an option of using up / down key to (incrementBy 1) / (incrementBy -1).

.... 


For that part, if you can use, for example, + and - instead of the arrow keys, you can do it with the same approach in my other replies.

 

But I recall something similar coming up, fairly recently, though I haven't found the thread yet.  It was about placing automatically-incrementing numerical Text with successive picks, and they wanted to be able to re-use the latest numerical value without incrementing it, that is, place more than one piece of Text with the same number, by hitting a certain key or key combination to back off the incrementing.  I don't remember whether it was a character or a non-character like the arrow keys or some Ctrl- or Shift- combination, but if you can find it [or if someone else knows where it is], there may be an answer there.

Kent Cooper, AIA
Message 8 of 8
PatrickHughes
in reply to: Anonymous

I've got a couple of lisp files on my download page that will give you example of the GREAD function. AutoUCS.lsp and AutoDim.lsp

 

EngDS Downloads

 

There is also a utility that provides some keyword formatting options that I've found to be helpful.

Patrick Hughes

Engineered Design Solutions
Developer of CadTempo - Cad Time Tracking
www.cadtempo.com

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost