Keyboard Control

Post

Posted
Rating:
#1 (In Topic #1417)
Regular
rj71 is in the usergroup ‘Regular’
 Hi all, I have an app I'd like to control using a keyboard (sometime in the future this might be a old xbox controller or Linux friendly remote) instead of a mouse. I understand keypress and keyrelease but what about navigating around the form to the buttons using arrow keys? So basically if my form has 6 buttons on it, I'd like to use the arrow keys to "go" to one of the buttons and then keypress to click it. Sort of like the Button1_Enter and Button1_Leave (Thanks Bruce!) events but with a keyboard. Not asking for code, just wondering if someone can point me in the right direction.
Online now: No Back to the top

Post

Posted
Rating:
#2
Guru
BruceSteers is in the usergroup ‘Guru’
Just make your application use QT.  (gb.gui.qt)

pretty sure it's the default behavior for QT GUIs

Except the space bar is usually the press button key
Because usually you set 1 button in a window to have it's Button.Default = True and one other to have Button.Cancel = True
The button that has Cancel = True should click when pressing escape and the one that's Default click when pressing Enter/Return

or maybe something like this…

Code (gambas)

  1.  
  2. Public Sub Form_KeyPress()
  3.  
  4.  ' If using gb.gui and maybe GTK+ then we operate manually or if QT then skip doing anything and let the toolkit function as normal.
  5. If Env["GB_GUI"] Like "gb.qt*" Then Return
  6.  
  7. If Not Application.ActiveContol Then Return  ' we are going to use Application.ActiveControl
  8.  
  9. If Key.Code = Key.Right Then
  10.  Try Application.ActiveControl.Next.SetFocus
  11.   Stop Event ' cancel anything else doing anything with the keypress
  12.  Try Application.ActiveControl.Previous.SetFocus
  13.   Stop Event ' cancel anything else doing anything with the keypress
  14.  
  15. Else If Key.Code = Key.Space Or If Key.Code = Key.Enter Or If Key.Code = Key.Return Then ' remove Enter and Return if using Default/Cancel buttons.
  16.   Try Object.Raise(Application.ActiveControl, "Click")
  17.   Stop Event ' cancel anything else doing anything with the keypress
  18.  
  19.  
  20.  
Online now: No Back to the top

Post

Posted
Rating:
#3
Avatar
Regular
thatbruce is in the usergroup ‘Regular’
Even with QT this can sometimes be incorrect.
Problems occur when there are containers that can gain focus or there are read-only or hidden controls in the way. Also Bruce's suggestion depends on the tab order of the controls (and wont wrap around if you want that.)
I would use explicit SetFocus calls and specific event handlers for each button. Like:

Code (gambas)

  1. Public Sub btn2_KeyPress()
  2.  
  3.   Select Key.Code
  4.     Case Key.Right
  5.       btn3.SetFocus
  6.     Case Key.Left
  7.       btn1.SetFocus
  8.  
  9.  
b

Online now: No Back to the top

Post

Posted
Rating:
#4
Regular
rj71 is in the usergroup ‘Regular’

BruceSteers said

Just make your application use QT.  (gb.gui.qt)

pretty sure it's the default behavior for QT GUIs

Except the space bar is usually the press button key
Because usually you set 1 button in a window to have it's Button.Default = True and one other to have Button.Cancel = True
The button that has Cancel = True should click when pressing escape and the one that's Default click when pressing Enter/Return

or maybe something like this…

Code (gambas)

  1.  
  2. Public Sub Form_KeyPress()
  3.  
  4.  ' If using gb.gui and maybe GTK+ then we operate manually or if QT then skip doing anything and let the toolkit function as normal.
  5. If Env["GB_GUI"] Like "gb.qt*" Then Return
  6.  
  7. If Not Application.ActiveContol Then Return  ' we are going to use Application.ActiveControl
  8.  
  9. If Key.Code = Key.Right Then
  10.  Try Application.ActiveControl.Next.SetFocus
  11.   Stop Event ' cancel anything else doing anything with the keypress
  12.  Try Application.ActiveControl.Previous.SetFocus
  13.   Stop Event ' cancel anything else doing anything with the keypress
  14.  
  15. Else If Key.Code = Key.Space Or If Key.Code = Key.Enter Or If Key.Code = Key.Return Then ' remove Enter and Return if using Default/Cancel buttons.
  16.   Try Object.Raise(Application.ActiveControl, "Click")
  17.   Stop Event ' cancel anything else doing anything with the keypress
  18.  
  19.  
  20.  
Thanks Bruce! That will get me started. I feel like I should be paying you for all the times you've helped me  :lol:
Online now: No Back to the top

Post

Posted
Rating:
#5
Regular
rj71 is in the usergroup ‘Regular’

thatbruce said

Even with QT this can sometimes be incorrect.
Problems occur when there are containers that can gain focus or there are read-only or hidden controls in the way. Also Bruce's suggestion depends on the tab order of the controls (and wont wrap around if you want that.)
I would use explicit SetFocus calls and specific event handlers for each button. Like:

Code (gambas)

  1. Public Sub btn2_KeyPress()
  2.  
  3.   Select Key.Code
  4.     Case Key.Right
  5.       btn3.SetFocus
  6.     Case Key.Left
  7.       btn1.SetFocus
  8.  
  9.  
b


Thanks Other Bruce! That looks super simple and I'll give that a try tomorrow. Thanks to both Bruces again!
Online now: No Back to the top

Post

Posted
Rating:
#6
Avatar
Guru
cogier is in the usergroup ‘Guru’
This may, or may not, interest you, but it was interesting trying to get it all to work.
There is a command line tool that will click the mouse called xdotool (X11 only) that I have used and will need to be installed for this to work!
While testing I found the space bar clicks buttons even if the mouse is nowhere near, so I have used [F12]!
The advantage I see in this code is simplification.

Code (gambas)

  1. Public Sub Form_KeyPress()
  2.  
  3.   Dim iMouseMove As Integer = 15 'How far the mouse moves with each keypress
  4.  
  5.   If Key.Code = Key.Right Then Mouse.Move(Mouse.ScreenX + iMouseMove, Mouse.ScreenY)
  6.   If Key.Code = Key.Left Then Mouse.Move(Mouse.ScreenX - iMouseMove, Mouse.ScreenY)
  7.   If Key.Code = Key.Up Then Mouse.Move(Mouse.ScreenX, Mouse.ScreenY - iMouseMove)
  8.   If Key.Code = Key.Down Then Mouse.Move(Mouse.ScreenX, Mouse.ScreenY + iMouseMove)
  9.   If Key.Code = Key.F12 Then Shell "xdotool click 1" 'Creates a left mouse click
  10.  
  11.  
  12. Public Sub AllBts_Click()
  13.  
  14.   Me.Title = "You have activated button " & Last.Text
  15.  

Here is the program
Attachment
Online now: No Back to the top

Post

Posted
Rating:
#7
Regular
rj71 is in the usergroup ‘Regular’

cogier said

This may, or may not, interest you, but it was interesting trying to get it all to work.
There is a command line tool that will click the mouse called xdotool (X11 only) that I have used and will need to be installed for this to work!
While testing I found the space bar clicks buttons even if the mouse is nowhere near, so I have used [F12]!
The advantage I see in this code is simplification.

Code (gambas)

  1. Public Sub Form_KeyPress()
  2.  
  3.   Dim iMouseMove As Integer = 15 'How far the mouse moves with each keypress
  4.  
  5.   If Key.Code = Key.Right Then Mouse.Move(Mouse.ScreenX + iMouseMove, Mouse.ScreenY)
  6.   If Key.Code = Key.Left Then Mouse.Move(Mouse.ScreenX - iMouseMove, Mouse.ScreenY)
  7.   If Key.Code = Key.Up Then Mouse.Move(Mouse.ScreenX, Mouse.ScreenY - iMouseMove)
  8.   If Key.Code = Key.Down Then Mouse.Move(Mouse.ScreenX, Mouse.ScreenY + iMouseMove)
  9.   If Key.Code = Key.F12 Then Shell "xdotool click 1" 'Creates a left mouse click
  10.  
  11.  
  12. Public Sub AllBts_Click()
  13.  
  14.   Me.Title = "You have activated button " & Last.Text
  15.  

Here is the program
Test-0.1.tar.gz


Thanks cogier. I'm familiar with xdotool and what you have done looks really interesting. What both Bruces gave me was enough to get me pointed in the right direction. This app I'm working is turning out to be really cool and fun to work on.
Online now: No Back to the top
1 guest and 0 members have just viewed this.