Page 1 of 1

How to Enable key press options to a ButtonGadget()

Posted: Thu Nov 19, 2020 4:21 pm
by C87
I would like to add functions to a ButtonGadget() so that when a user presses <Enter> I can decide on the next event. This is in addition to
the standard mouse-click.

Also, I would like to include an accelerator key to a button.

The reason being that on a data entry screen switching from keyboard to mouse and back again is timewasting and irritating.

As an example I have amended the program from Page 143 of the PureBasic Beginners Guide making it nearer to something that I may have written.
I have added new fields and a 3rd button as well as changing the variable names to something I prefer. In case any new users are interested I have
included additions that they may find helpful for a data entry screen.
( I am not suggesting to a new user that this code is a template for a data-entry screen, it is maybe a starting point. A system would really require the use
of Procedures and Modules to reduce duplication and make it easier to maintain)

Code: Select all

;╔════════════╦═════════════════════════════════════════════════════════════════════════════════════════════╗
;║ ██████████ ║ Simple input window with just three input fields & three buttons                            ║
;║            ║ The problem is that the buttons need to be selected by <Enter> or an accelerator key        ║
;║            ║ The operation of keyboard, mouse, keyboard are unsatisfactory for data entry                ║
;║            ║                                                                                             ║
;║            ║ Ideally I would like a button activated with <Enter> or to allow the user to jump to a      ║
;║            ║ particular button with an accelerator key, usually indicated and set with an underline _ to ║
;║            ║ a letter in the buton text. This is often set with the '&' So E&xit shows the x underlined. ║
;║            ║ It is usualy activated with the <Alt> plus the letter key. The buttons here show underlined ║
;║            ║ but are not activated using the <Alt> key. Basically addions to mouse click selections      ║
;║            ║ What I want to do avoids the keyboard, mouse, keyboard, sequence which reduces data entry   ║
;║            ║ times and can be irritating to the user                                                     ║
;║   C87      ║  NOTES:                                                                                     ║
;║            ║ Simple code adapted from PureB Beginners Guide from page 143 as an example. I have added a  ║
;║            ║ a few basic bells & whistles which some may find a little helpful, no in depth stuff though ║
;║            ║ An actual system will no doubt include procedures, modules etc to remove duplication.       ║
;║            ║ Data entry code should be written with the object of maintaining control of what the user   ║
;║            ║ can enter, or leave out.                                                                    ║
;╚════════════╩═════════════════════════════════════════════════════════════════════════════════════════════╝
;
EnableExplicit
;
Enumeration
  #WIN_MAIN
  #Code0    ; could use #PB_Any in place of these
  #Name1    ;    ditto
  #Addr1    ;    ditto
  #Code_10
  #Name_10
  #Addr_10
  #Btn_Save
  #Btn_AddNew
  #Btn_Exit
  #ExitYN
  #AddYN
EndEnumeration
;
Global.l AddYN, ExitYN, Event
;
Global Quit.b = #False
  #FLAGS = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
If OpenWindow(#WIN_MAIN, 0, 0, 500, 230, "SIMPLE INPUT SCREEN EXAMPLE {Problem no ◄─┘ accepted} ", #FLAGS)
  ; 
  TextGadget(#Code0, 10, 10, 50, 20, "Code ",    #PB_Text_Right)
  TextGadget(#Name1, 10, 40, 50, 20, "Name ",    #PB_Text_Right)
  TextGadget(#Addr1, 10, 70, 50, 20, "Address ", #PB_Text_Right)
  ;
  StringGadget(#Code_10, 70, 10,  90, 20, "", #PB_String_UpperCase)    : SetGadgetAttribute(#Code_10, #PB_String_MaximumLength, 8)  ; control the length of the field entered
  StringGadget(#Name_10, 70, 40, 200, 20, "")                          : SetGadgetAttribute(#Name_10, #PB_String_MaximumLength, 16)  
  StringGadget(#Addr_10, 70, 70, 300, 20, "")                          : SetGadgetAttribute(#Addr_10, #PB_String_MaximumLength, 32)  
  ;
  ButtonGadget(#Btn_Save,    10, 170, 120,30, "&Save Entry")  ; yes I know the underline doesn't show initially, but that isn't important for this 
  ButtonGadget(#Btn_AddNew, 220, 170, 90, 30, "&Add New")
  ButtonGadget(#Btn_Exit,   390, 170, 100,30, "E&xit")
  ;
  ; There may be more buttons, for instance [Next] and [Back] buttons to allow the user to move around to select and display a record. 
  ; Those types of key are quick and easy to use with <Enter> or an accelerator key. Function keys are another alternative.
  ;
  ; Entering the gadgets in the tab order you want naturally set the tab order in use, which is simple and trouble free
  ; The fields and buttons on the screen show the cursor location on editing and after pressing the TAB key
  ;
  SetActiveGadget(#Code_10) ; SetFocus
  Repeat
    Event.l = WaitWindowEvent()
    Select Event
    Case #PB_Event_Gadget
      Select EventGadget()
      Case #Btn_Save
        MessageRequester("Button Selected", "Record Saved",   #PB_MessageRequester_Info)  
      Case #Btn_AddNew  
        ; adding a MessageRequester() to a button provides the user with a check before accepting changes. 
        ; The MessageRequester() has set return values as PureBasic constants but I find it easier, and quicker to user the numeric values. 
        AddYN = MessageRequester("Button Selected", "Add New Record", #PB_MessageRequester_YesNo)  ; Auto on Yes, so can press <Enter> to continue
        ; AddNewRecord()
        If AddYN = 6 
          ; After adding, clear screen and shift cursor to 1st data entry field
          StringGadget(#Code_10, 70, 10, 90,  20,"", #PB_String_UpperCase)     : SetGadgetAttribute(#Code_10, #PB_String_MaximumLength, 8) 
          StringGadget(#Name_10, 70, 40, 200, 20, "")                          : SetGadgetAttribute(#Name_10, #PB_String_MaximumLength, 16)  
          StringGadget(#Addr_10, 70, 70, 300, 20, "")                          : SetGadgetAttribute(#Addr_10, #PB_String_MaximumLength, 32)  
  ;
          SetActiveGadget(#Code_10) ; SetFocus  Moves to 1st entry field before entering data for the next field.
        EndIf
      Case #Btn_Exit
        ExitYN = MessageRequester("Button Selected Exit", "You have selected to close the screen", #PB_MessageRequester_YesNo)
        If ExitYN <> 6
          MessageRequester("EXIT OPTION", "Abandonded",              #PB_MessageRequester_Info)
        Else
          MessageRequester("EXIT OPTION", "Exiting Add/Edit Screen", #PB_MessageRequester_Warning)  ; This option is not reqd and is just an example of a Warning Msg
          Quit = #True                                                                              ; sometimes it is a good idea to tell the user what they have done
        EndIf
      EndSelect
    EndSelect
  Until Event = #PB_Event_CloseWindow Or Quit = #True
  ;
EndIf
;
End
; 
; ┌───────────────────────────────────────────────────────┐
; │ ██████████    SIMPLE INPUT SCREEN END      ██████████ │
; └───────────────────────────────────────────────────────┘   

Re: How to Enable key press options to a ButtonGadget()

Posted: Thu Nov 19, 2020 5:03 pm
by RASHAD
Hi

Code: Select all

EnableExplicit
;
Macro ctrl_S
 MessageRequester("Button Selected", "Record Saved",   #PB_MessageRequester_Info)
EndMacro

Macro ctrl_A
  AddYN = MessageRequester("Button Selected", "Add New Record", #PB_MessageRequester_YesNo)  ; Auto on Yes, so can press <Enter> to continue
  ; AddNewRecord()
  If AddYN = 6
    ; After adding, clear screen and shift cursor to 1st data entry field
    StringGadget(#Code_10, 70, 10, 90,  20,"", #PB_String_UpperCase)     : SetGadgetAttribute(#Code_10, #PB_String_MaximumLength, 8)
    StringGadget(#Name_10, 70, 40, 200, 20, "")                          : SetGadgetAttribute(#Name_10, #PB_String_MaximumLength, 16) 
    StringGadget(#Addr_10, 70, 70, 300, 20, "")                          : SetGadgetAttribute(#Addr_10, #PB_String_MaximumLength, 32) 
  ;
    SetActiveGadget(#Code_10) ; SetFocus  Moves to 1st entry field before entering data for the next field.
  EndIf
EndMacro

Macro ctrl_X
  ExitYN = MessageRequester("Button Selected Exit", "You have selected to close the screen", #PB_MessageRequester_YesNo)
  If ExitYN <> 6
    MessageRequester("EXIT OPTION", "Abandonded",              #PB_MessageRequester_Info)
  Else
    MessageRequester("EXIT OPTION", "Exiting Add/Edit Screen", #PB_MessageRequester_Warning)  ; This option is not reqd and is just an example of a Warning Msg
    Quit = #True                                                                              ; sometimes it is a good idea to tell the user what they have done
  EndIf
EndMacro
Enumeration
  #WIN_MAIN
  #Code0    ; could use #PB_Any in place of these
  #Name1    ;    ditto
  #Addr1    ;    ditto
  #Code_10
  #Name_10
  #Addr_10
  #Btn_Save
  #Btn_AddNew
  #Btn_Exit
  #ExitYN
  #AddYN
EndEnumeration
;
Global.l AddYN, ExitYN, Event
;
Global Quit.b = #False
  #FLAGS = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
If OpenWindow(#WIN_MAIN, 0, 0, 500, 230, "SIMPLE INPUT SCREEN EXAMPLE {Problem no ◄─┘ accepted} ", #FLAGS)
  ;
  TextGadget(#Code0, 10, 10, 50, 20, "Code ",    #PB_Text_Right)
  TextGadget(#Name1, 10, 40, 50, 20, "Name ",    #PB_Text_Right)
  TextGadget(#Addr1, 10, 70, 50, 20, "Address ", #PB_Text_Right)
  ;
  StringGadget(#Code_10, 70, 10,  90, 20, "", #PB_String_UpperCase)    : SetGadgetAttribute(#Code_10, #PB_String_MaximumLength, 8)  ; control the length of the field entered
  StringGadget(#Name_10, 70, 40, 200, 20, "")                          : SetGadgetAttribute(#Name_10, #PB_String_MaximumLength, 16) 
  StringGadget(#Addr_10, 70, 70, 300, 20, "")                          : SetGadgetAttribute(#Addr_10, #PB_String_MaximumLength, 32) 
  ;
  ButtonGadget(#Btn_Save,    10, 170, 120,30, "&Save Entry")  ; yes I know the underline doesn't show initially, but that isn't important for this
  ButtonGadget(#Btn_AddNew, 220, 170, 90, 30, "&Add New")
  ButtonGadget(#Btn_Exit,   390, 170, 100,30, "E&xit")
  ;
  ; There may be more buttons, for instance [Next] and [Back] buttons to allow the user to move around to select and display a record.
  ; Those types of key are quick and easy to use with <Enter> or an accelerator key. Function keys are another alternative.
  ;
  ; Entering the gadgets in the tab order you want naturally set the tab order in use, which is simple and trouble free
  ; The fields and buttons on the screen show the cursor location on editing and after pressing the TAB key
  ;
  SetActiveGadget(#Code_10) ; SetFocus
  AddKeyboardShortcut(0, #PB_Shortcut_Return, 10)
  AddKeyboardShortcut(0, #PB_Shortcut_Control|#PB_Shortcut_S, 20)
  AddKeyboardShortcut(0, #PB_Shortcut_Control|#PB_Shortcut_A, 30)
  AddKeyboardShortcut(0, #PB_Shortcut_Control|#PB_Shortcut_X, 40)
  SendMessage_(WindowID(0), #WM_UPDATEUISTATE, 3<<16|2 ,0)
  Repeat
    Event.l = WaitWindowEvent()
    Select Event
    Case #PB_Event_Menu
      Select EventMenu()
        Case 10          
          If GetActiveGadget() = #Btn_Exit
            SetActiveGadget(#Code_10)
          Else
            SetActiveGadget(GetActiveGadget()+1)
          EndIf
          
        Case 20
          ctrl_S
          
        Case 30
          ctrl_A
          
        Case 40
          ctrl_X
      EndSelect
    Case #PB_Event_Gadget
      Select EventGadget()
      Case #Btn_Save
        ctrl_S;MessageRequester("Button Selected", "Record Saved",   #PB_MessageRequester_Info)
        
      Case #Btn_AddNew 
        ctrl_A
        
      Case #Btn_Exit
        ctrl_X
        
      EndSelect
    EndSelect
  Until Event = #PB_Event_CloseWindow Or Quit = #True
  ;
EndIf
;
End
;
; ┌───────────────────────────────────────────────────────┐
; │ ██████████    SIMPLE INPUT SCREEN END      ██████████ │
; └───────────────────────────────────────────────────────┘   

Re: How to Enable key press options to a ButtonGadget()

Posted: Thu Nov 19, 2020 6:14 pm
by C87
Many thanks for your help Rashad
Bill
(C87)