Detecting gadget focus when Tabbing to it

Just starting out? Need help? Post your questions and find answers here.
BarryG
Addict
Addict
Posts: 4134
Joined: Thu Apr 18, 2019 8:17 am

Detecting gadget focus when Tabbing to it

Post 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
User avatar
TI-994A
Addict
Addict
Posts: 2702
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Detecting gadget focus when Tabbing to it

Post 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
Last edited by TI-994A on Thu Feb 18, 2021 6:58 am, edited 1 time in total.
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
BarryG
Addict
Addict
Posts: 4134
Joined: Thu Apr 18, 2019 8:17 am

Re: Detecting gadget focus when Tabbing to it

Post 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.
infratec
Always Here
Always Here
Posts: 7587
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: Detecting gadget focus when Tabbing to it

Post 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
User avatar
TI-994A
Addict
Addict
Posts: 2702
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Detecting gadget focus when Tabbing to it

Post 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.
Texas Instruments TI-99/4A Home Computer: the first home computer with a 16bit processor, crammed into an 8bit architecture. Great hardware - Poor design - Wonderful BASIC engine. And it could talk too! Please visit my YouTube Channel :D
BarryG
Addict
Addict
Posts: 4134
Joined: Thu Apr 18, 2019 8:17 am

Re: Detecting gadget focus when Tabbing to it

Post 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.
User avatar
chi
Addict
Addict
Posts: 1087
Joined: Sat May 05, 2007 5:31 pm
Location: Austria

Re: Detecting gadget focus when Tabbing to it

Post 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]
Et cetera is my worst enemy
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: Detecting gadget focus when Tabbing to it

Post 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
Egypt my love
BarryG
Addict
Addict
Posts: 4134
Joined: Thu Apr 18, 2019 8:17 am

Re: Detecting gadget focus when Tabbing to it

Post 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.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: Detecting gadget focus when Tabbing to it

Post 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
Egypt my love
BarryG
Addict
Addict
Posts: 4134
Joined: Thu Apr 18, 2019 8:17 am

Re: Detecting gadget focus when Tabbing to it

Post 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.
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4946
Joined: Sun Apr 12, 2009 6:27 am

Re: Detecting gadget focus when Tabbing to it

Post 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
Egypt my love
BarryG
Addict
Addict
Posts: 4134
Joined: Thu Apr 18, 2019 8:17 am

Re: Detecting gadget focus when Tabbing to it

Post 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.
Post Reply