Page 1 of 1

Make options selectable with the keyboard, too

Posted: Tue Jun 29, 2021 9:02 pm
by Little John
PureBasic doesn't have built-in support for changing the selected option within a group by using the up/down keys.
(The TAB key shouldn't do that, but pressing TAB should leave the whole option group -- remembering which option is selected --, and activate another control.)
Occasionally this support was built-in (e.g. in PureBasic 5.45 LTS Beta 1), but then it was dropped again.

So here is some native cross-platform PB code for making options selectable not only with the mouse, but also with the keyboard.

Additionally, this code shows how to implement the OK button as the default button.

Code: Select all

; Make options selectable with the keyboard, too;
; by Little John 2021
; <https://www.purebasic.fr/english/viewtopic.php?f=12&t=77523>

; successfully tested with PB 5.73 on
; - Windows 10
; - Linux Mint 19.3

EnableExplicit

; Windows
Enumeration
   #Win_Main
EndEnumeration

; Gadgets
Enumeration
   #Opt_0
   #Opt_1
   #Opt_2
   #Btn_OK
   #Btn_Cancel
EndEnumeration

; Keyboard shortcuts
Enumeration
   #Key_Up
   #Key_Down
   #Key_Return
EndEnumeration


Define.i event, option, wrap

;--------------------
; Settings
option = #Opt_1
wrap = #False
;--------------------

If OpenWindow(#Win_Main, 0, 0, 200, 170, "OptionGadget", #PB_Window_SystemMenu |
                                                         #PB_Window_ScreenCentered) = 0
   MessageRequester("Fatal error", "Can't open main window.")
   End
EndIf

OptionGadget(#Opt_0, 60, 20, 70, 20, "Option 0")
OptionGadget(#Opt_1, 60, 45, 70, 20, "Option 1")
OptionGadget(#Opt_2, 60, 70, 70, 20, "Option 2")
FrameGadget(#PB_Any, 50,  5, 90, 90, "")

ButtonGadget(#Btn_OK,      20, 120, 60, 30, "OK", #PB_Button_Default)
ButtonGadget(#Btn_Cancel, 100, 120, 80, 30, "Cancel")

SetGadgetState(option, 1)
SetActiveGadget(option)

AddKeyboardShortcut(#Win_Main, #PB_Shortcut_Up, #Key_Up)
AddKeyboardShortcut(#Win_Main, #PB_Shortcut_Down, #Key_Down)
AddKeyboardShortcut(#Win_Main, #PB_Shortcut_Return, #Key_Return)  ; enable a default button

Repeat
   event = WaitWindowEvent()
   
   Select event
      Case #PB_Event_Menu
         Select EventMenu()
            Case #Key_Up
               Select GetActiveGadget()
                  Case #Opt_1 To #Opt_2
                     option = GetActiveGadget() - 1
                     SetGadgetState(option, 1)
                     SetActiveGadget(option)
                  Case #Opt_0
                     If wrap = #True
                        option = #Opt_2
                        SetGadgetState(option, 1)
                        SetActiveGadget(option)
                     EndIf   
               EndSelect
               
            Case #Key_Down
               Select GetActiveGadget()
                  Case #Opt_0 To #Opt_1
                     option = GetActiveGadget() + 1
                     SetGadgetState(option, 1)
                     SetActiveGadget(option)
                  Case #Opt_2
                     If wrap = #True
                        option = #Opt_0
                        SetGadgetState(option, 1)
                        SetActiveGadget(option)
                     EndIf   
               EndSelect
               
            Case #Key_Return             ; make #Btn_OK behave as default button          
               Select GetActiveGadget()
                  Case #Btn_Cancel
                     PostEvent(#PB_Event_Gadget, #Win_Main, #Btn_Cancel)
                  Default
                     PostEvent(#PB_Event_Gadget, #Win_Main, #Btn_OK)
               EndSelect
         EndSelect
         
      Case #PB_Event_Gadget
         Select EventGadget()
            Case #Opt_0 To #Opt_2
               option = EventGadget()
               
            Case #Btn_OK
               Debug "You chose option " + option
               
            Case #Btn_Cancel
               Debug "Canceled"
               Break
         EndSelect
   EndSelect
Until event = #PB_Event_CloseWindow
CloseWindow(#Win_Main)

Re: Make options selectable with the keyboard, too

Posted: Wed Jun 30, 2021 2:40 pm
by RASHAD
Hi LJ
Saved to my archive
Could not resist coding with another tech.

Code: Select all


If OpenWindow(0, 450, 200, 400, 400, "Window_0", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
  ButtonGadget(0, 57, 20, 194, 39, "Gadget_0")
  OptionGadget(1, 58, 86, 198, 26, "Gadget_1")
  OptionGadget(2, 58, 117, 198, 26, "Gadget_2")
  OptionGadget(3, 58, 148, 198, 26, "Gadget_3")
  OptionGadget(4, 58, 179, 198, 26, "Gadget_4")
  OptionGadget(5, 58, 210, 198, 26, "Gadget_5")
  
  ButtonGadget(6, 54, 254, 212, 42, "Gadget_6")
  CheckBoxGadget(7, 58, 300, 198, 26, "Gadget_7")

  SetGadgetState(2,1)
  SetActiveGadget(2)
  
  AddKeyboardShortcut(0,#PB_Shortcut_Up,10)
  AddKeyboardShortcut(0,#PB_Shortcut_Down,20)  
  
  Repeat  
    Select WaitWindowEvent()
      Case #PB_Event_Menu
        Select EventMenu()
          Case 10
            If GadgetType(GetActiveGadget()) = #PB_GadgetType_Option 
              act = GetActiveGadget()   
              SetGadgetState(act-1,1)
              If act = 1
                act = 2
              EndIf                  
              SetActiveGadget(act-1)
            EndIf
            
          Case 20
            If GadgetType(GetActiveGadget()) = #PB_GadgetType_Option 
              act = GetActiveGadget()                     
              SetGadgetState(act+1,1)
              If act = 5
                act = 4
              EndIf                  
              SetActiveGadget(act+1)   
            EndIf
        EndSelect    
        
      Case #PB_Event_CloseWindow
        Quit = 1
        
    EndSelect   
  Until Quit = 1
EndIf

Re: Make options selectable with the keyboard, too

Posted: Wed Jun 30, 2021 3:59 pm
by Kwai chang caine
This two codes works perfectly here
Thanks for sharing 8)