Page 1 of 1

Detecting gadget focus when Tabbing to it

Posted: Wed Feb 17, 2021 3:30 pm
by BarryG
Hi all, having a mental blank here and can't work this out... all I want to do is make each button have an asterisk put on it when I press the Tab key (not mouse click!) to give it the focus.

But this code doesn't work, and there's no #PB_Event_GadgetFocus event... so how would I do this? Thanks.

See last code below for my hack solution.

Code: Select all

If OpenWindow(0, 200, 200, 270, 100, "Press Tab a few times", #PB_Window_SystemMenu)

  ButtonGadget(1, 10, 10, 250, 21, "")
  ButtonGadget(2, 10, 40, 250, 21, "")
  ButtonGadget(3, 10, 70, 250, 21, "")
  
  SetActiveGadget(1)
  
  Repeat
    ev=WaitWindowEvent()
    If ev=#PB_Event_Gadget
      SetGadgetText(EventGadget(),"*")
    EndIf
  Until ev = #PB_Event_CloseWindow

EndIf
This also doesn't work:

Code: Select all

If OpenWindow(0, 200, 200, 270, 100, "Press Tab a few times", #PB_Window_SystemMenu)
  
  ButtonGadget(1, 10, 10, 250, 21, "")
  ButtonGadget(2, 10, 40, 250, 21, "")
  ButtonGadget(3, 10, 70, 250, 21, "")
  
  SetActiveGadget(1)
  
  Repeat
    ev=WaitWindowEvent()
    If ev=#PB_Event_Gadget
      If EventType()=#PB_EventType_Focus
        SetGadgetText(EventGadget(),"*")
      EndIf
    EndIf
  Until ev = #PB_Event_CloseWindow
  
EndIf
I've done the below for now, but surely there's a better/cleaner/non-hack way?

Code: Select all

If OpenWindow(0, 200, 200, 270, 100, "Press Tab a few times", #PB_Window_SystemMenu)
  
  ButtonGadget(1, 10, 10, 250, 21, "")
  ButtonGadget(2, 10, 40, 250, 21, "")
  ButtonGadget(3, 10, 70, 250, 21, "")
  
  Repeat
    ev=WaitWindowEvent()
    newfocus=GetActiveGadget()
    If newfocus<>-1 And newfocus<>oldfocus
      oldfocus=newfocus
      SetGadgetText(newfocus,"*")
    EndIf
  Until ev = #PB_Event_CloseWindow
  
EndIf

Re: Detecting gadget focus when Tabbing to it

Posted: Wed Feb 17, 2021 3:48 pm
by TI-994A
BarryG wrote:...make each button have an asterisk put on it when I press the Tab key (not mouse click!) to give it the focus.
Since not all gadgets trigger the focus event, try something like this:

*EDIT: Modified to handle back tabbing as well (Shift-Tab):

Code: Select all

#gadgetTab = 99
#gadgetTabBack = 98

Procedure gadgetHandler(activeGadget)
  
  For i = 1 To 3
    If i = activeGadget
      title$ = "***"
    Else
      title$ = ""
    EndIf    
    SetGadgetText(i, title$)
  Next i     
  SetActiveGadget(activeGadget)  
  
EndProcedure

If OpenWindow(0, 200, 200, 270, 100, "Gadget Tabbing", #PB_Window_SystemMenu)
  
  ButtonGadget(1, 10, 10, 250, 21, "***")
  ButtonGadget(2, 10, 40, 250, 21, "")
  ButtonGadget(3, 10, 70, 250, 21, "")
  
  AddKeyboardShortcut(0, #PB_Shortcut_Tab, #gadgetTab)
  AddKeyboardShortcut(0, #PB_Shortcut_Shift | #PB_Shortcut_Tab, #gadgetTabBack)
  
  SetActiveGadget(1)
  
  activeGadget = GetActiveGadget()
  
  Repeat
    
    Select WaitWindowEvent()
        
      Case #PB_Event_CloseWindow
        appQuit = #True
        
      Case #PB_Event_Menu        
        Select EventMenu()
            
          Case #gadgetTab            
            activeGadget + 1
            If activeGadget > 3
              activeGadget = 1
            EndIf          
            gadgetHandler(activeGadget)                   
            
          Case #gadgetTabBack
            activeGadget - 1
            If activeGadget < 1
              activeGadget = 3
            EndIf          
            gadgetHandler(activeGadget)                   
            
        EndSelect
        
      Case #PB_Event_Gadget
        activeGadget = EventGadget()
        gadgetHandler(activeGadget)
        
    EndSelect
    
  Until appQuit 
  
EndIf

Re: Detecting gadget focus when Tabbing to it

Posted: Wed Feb 17, 2021 3:58 pm
by BarryG
TI-994A wrote:not all gadgets trigger the focus event
So, that's the real issue, isn't it? Both mine and your solution (with AddKeyboardShortcut) are just hacks to make it work. Oh well. Feature request posted.

And thanks for reading my post and coming up with an alternative way to make it work. I do appreciate the time you took.

Re: Detecting gadget focus when Tabbing to it

Posted: Wed Feb 17, 2021 4:03 pm
by infratec
If you read the help for ButtonGadget(), you will read nothing about EventTypes.
A ButtonGadet() generates no EventType messages.

So you need your latest version.

My extended version:

Code: Select all

EnableExplicit


Enumeration
  #ButtonStart
  #Button1
  #Button2
  #Button3
  #ButtonEnd
EndEnumeration


Define.i ev, LastActiveButtonGadget, ActiveGadget

If OpenWindow(0, 200, 200, 270, 100, "Press Tab a few times", #PB_Window_SystemMenu)
  
  ButtonGadget(#Button1, 10, 10, 250, 21, "")
  ButtonGadget(#Button2, 10, 40, 250, 21, "")
  ButtonGadget(#Button3, 10, 70, 250, 21, "")
  
  SetActiveGadget(#Button1)
  
  Repeat
    ev=WaitWindowEvent()
    
    ActiveGadget = GetActiveGadget()
    If ActiveGadget > #ButtonStart And ActiveGadget < #ButtonEnd
      If LastActiveButtonGadget <> ActiveGadget
        If LastActiveButtonGadget <> 0
          SetGadgetText(LastActiveButtonGadget, "")
        EndIf
        SetGadgetText(ActiveGadget, "*")
        LastActiveButtonGadget = ActiveGadget
      EndIf
    EndIf
    
  Until ev = #PB_Event_CloseWindow
  
EndIf

Re: Detecting gadget focus when Tabbing to it

Posted: Wed Feb 17, 2021 4:08 pm
by TI-994A
BarryG wrote:So, that's the real issue, isn't it?
The GetActiveGadget() function returns only gadgets that have keyboard input focus, and not really the currently selected gadget. So, manual track hacks for now.

Re: Detecting gadget focus when Tabbing to it

Posted: Wed Feb 17, 2021 4:09 pm
by BarryG
infratec wrote:If you read the help for ButtonGadget(), you will read nothing about EventTypes.
A ButtonGadet() generates no EventType messages.
Which is crazy! I can't believe that. Thanks for reading and posting your hack version, too.

Re: Detecting gadget focus when Tabbing to it

Posted: Wed Feb 17, 2021 6:44 pm
by chi
Don't know if you need a cross-platform solution, but on Windows you could do something like this

Code: Select all

Procedure WND_Hook(nCode, wParam, lParam)
  If nCode = #HCBT_SETFOCUS
    curr = GetDlgCtrlID_(wParam)
    If curr
      SetGadgetText(curr, "*" + GetGadgetText(curr))
    EndIf
    prev = GetDlgCtrlID_(lParam)    
    If prev
      SetGadgetText(prev, Trim(GetGadgetText(prev), "*"))
    EndIf    
  EndIf
  ProcedureReturn CallNextHookEx_(0, nCode, wParam, lParam) 
EndProcedure

hook = SetWindowsHookEx_(#WH_CBT, @WND_Hook(), 0, GetCurrentThreadId_())

OpenWindow(0, 0, 0, 270, 100, "", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
ButtonGadget(100, 10, 10, 250, 21, "button 1")
ButtonGadget(200, 10, 40, 250, 21, "button 2")
ButtonGadget(300, 10, 70, 250, 21, "button 3")
While WaitWindowEvent() <> #PB_Event_CloseWindow : Wend
UnhookWindowsHookEx_(hook)
[/size]

Re: Detecting gadget focus when Tabbing to it

Posted: Wed Feb 17, 2021 7:26 pm
by RASHAD
Hi BarryG
My 2 cents
You can use it for all kinds of Gadgets
#1 :

Code: Select all

Procedure watch(par)
  Repeat
    x1 = GadgetX(1,#PB_Gadget_ScreenCoordinate): x11 = x1 + 250
    y1 = GadgetY(1,#PB_Gadget_ScreenCoordinate): y11 = y1 + 21
    x2 = GadgetX(2,#PB_Gadget_ScreenCoordinate): x22 = x2 + 250
    y2 = GadgetY(2,#PB_Gadget_ScreenCoordinate): y22 = y2 + 21
    x3 = GadgetX(3,#PB_Gadget_ScreenCoordinate): x33 = x3 + 250
    y3 = GadgetY(3,#PB_Gadget_ScreenCoordinate): y33 = y3 + 21
    mx = DesktopMouseX() :my = DesktopMouseY() 
    If mx >= x1 And mx < x11 And my >= y1 And my < y11
      Debug "Over 1"
    ElseIf mx >= x2 And mx < x22 And my >= y2 And my < y22
      Debug "Over 2"
    ElseIf mx >= x3 And mx < x33 And my >= y3 And my < y33
      Debug "Over 3"
    Else
      Debug "None"
    EndIf
    Delay(10)
  ForEver
EndProcedure

If OpenWindow(0, 200, 200, 270, 100, "Press Tab a few times", #PB_Window_SystemMenu)
  ButtonGadget(1, 10, 10, 250, 21, "1")
  ButtonGadget(2, 10, 40, 250, 21, "2")
  ButtonGadget(3, 10, 70, 250, 21, "3")
  ;SetActiveGadget(1)
  thread = CreateThread(@watch(),30)
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Quit = 1
        
    EndSelect
  Until Quit = 1
  
EndIf
#2 :

Code: Select all

Procedure watch(par)
  Repeat
    x1 = GadgetX(1,#PB_Gadget_WindowCoordinate):x11 = x1+250
    y1 = GadgetY(1,#PB_Gadget_WindowCoordinate):y11 = y1+21
    x2 = GadgetX(2,#PB_Gadget_WindowCoordinate):x22 = x2+250
    y2 = GadgetY(2,#PB_Gadget_WindowCoordinate):y22 = y2+21
    x3 = GadgetX(3,#PB_Gadget_WindowCoordinate):x33 = x3+250
    y3 = GadgetY(3,#PB_Gadget_WindowCoordinate):y33 = y3+21 
    mx = WindowMouseX(0) :my = WindowMouseY(0)
    If mx >= x1 And mx < x11 And my >= y1 And my < y11
      Debug "Over 1"
    ElseIf mx >= x2 And mx < x22 And my >= y2 And my < y22
      Debug "Over 2"
    ElseIf mx >= x3 And mx < x33 And my >= y3 And my < y33
      Debug "Over 3"
    Else
      Debug "None"
    EndIf
    Delay(10)
  ForEver
EndProcedure

If OpenWindow(0, 200, 200, 270, 100, "Press Tab a few times", #PB_Window_SystemMenu)
  ButtonGadget(1, 10, 10, 250, 21, "1")
  ButtonGadget(2, 10, 40, 250, 21, "2")
  ButtonGadget(3, 10, 70, 250, 21, "3")

  ;SetActiveGadget(1)
  thread = CreateThread(@watch(),30)
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Quit = 1
       
    EndSelect
  Until Quit = 1
 
EndIf

Re: Detecting gadget focus when Tabbing to it

Posted: Thu Feb 18, 2021 3:17 am
by BarryG
Rashad, your examples only work with the mouse over - I specifically said when Tabbing between them with the keyboard <wink>.

BTW, I do have a small hack solution in place now, so don't waste any more time on it. It's all good for now.

Re: Detecting gadget focus when Tabbing to it

Posted: Thu Feb 18, 2021 5:12 am
by RASHAD
OK mate :mrgreen:
Did it for myself and maybe you will like it

Code: Select all

If OpenWindow(0, 200, 200, 270, 100, "Press Tab a few times", #PB_Window_SystemMenu)

  ButtonGadget(1, 10, 10, 250, 21, "")
  ButtonGadget(2, 10, 40, 250, 21, "")
  ButtonGadget(3, 10, 70, 250, 21, "")
 
  SetActiveGadget(1)
  AddWindowTimer(0,125,100)
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Quit = 1
        
      Case #PB_Event_Timer
        For i = 1 To 3
          SetGadgetText(i,"")
        Next
        SetGadgetText(GetActiveGadget(),"*")
        
    EndSelect
  Until Quit = 1

EndIf

Re: Detecting gadget focus when Tabbing to it

Posted: Thu Feb 18, 2021 5:45 am
by BarryG
Thanks for going one extra. I won't use a timer, though. My hack solution (using GetFocus_() API) is working great.

Thanks also to Chi for coming up with an alternative.

Re: Detecting gadget focus when Tabbing to it

Posted: Thu Feb 18, 2021 6:06 am
by RASHAD
No timer :P
Don't get mad ,I still have 10 more

Code: Select all

If OpenWindow(0, 200, 200, 270, 100, "Press Tab a few times", #PB_Window_SystemMenu)
  
  ButtonGadget(1, 10, 10, 250, 21, "")
  ButtonGadget(2, 10, 40, 250, 21, "")
  ButtonGadget(3, 10, 70, 250, 21, "")
  
  SetActiveGadget(1)
  SetGadgetText(1,"*")
  Repeat
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        Quit = 1
        
      Case #WM_KEYDOWN
        If EventwParam() = 9
          For i = 1 To 3
            SetGadgetText(i,"")
          Next
          SetGadgetText(GetActiveGadget(),"*")
        EndIf
        
    EndSelect
  Until Quit = 1  
EndIf

Re: Detecting gadget focus when Tabbing to it

Posted: Thu Feb 18, 2021 8:00 am
by BarryG
This whole thing came about because of ComboBoxGadgets, actually.

See here -> viewtopic.php?f=13&t=76761

But it's silly that ButtonGadgets don't respond to GetActiveGadget() too, because you can press the Space bar or Enter key on them.