Page 1 of 1

[SOLVED] StringGadgets, BingGadgetEvent, LostFocus and SetActiveGadget problem

Posted: Thu Sep 05, 2024 11:27 pm
by boddhi
Hello,

I want to check the validity of dates in StringGadget() when focus is lost.
Here's how it works: On focus, if there's no error for the current gadget, I store its contents (for future use not provided in the code). When the focus is lost, I check the validity of the date using a RegEX. If the date is invalid, I declare that the current gadget is in error using variables (to prevent the content from being retrieved when the focus is taken back) and wish to return the focus to the current gadget.
I use BindGadgetEvent() to handle events.

The problem is that the cursor disappears and it's impossible to bring it back, whatever StringGdaget I click on. :shock:

Code: Select all

EnableExplicit
; IMPORTANT: Dates must be in French format (DD/MM/YY or DD/MM/YYYY)
#REGEX_DATE=0
#DEFREGEX_DATEFORMAT="^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/)(?:0?[13-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$"
CreateRegularExpression(#REGEX_DATE,#DEFREGEX_DATEFORMAT)
;
Procedure   Pc_DateTypingControl()
  Protected.i Test
  Protected.u NoGadget=EventGadget(),NoEvenmt=EventType()
  Static.a StartDateError,EndDateError
  Static.s AncStartDate,AncEndDate,Date
  
  Select NoEvenmt
    Case #PB_EventType_Change
      ; [...]
    Case #PB_EventType_Focus ; Get the content of the gadget if no previous error
      Select NoGadget
          Case 0:If Not StartDateError:AncStartDate=GetGadgetText(0):EndIf
          Case 1:If Not EndDateError:AncEndDate=GetGadgetText(1):EndIf
      EndSelect
    Case #PB_EventType_LostFocus
      Date=GetGadgetText(NoGadget)
      Test=Bool(MatchRegularExpression(#REGEX_DATE,Date))!1
      Select NoGadget
        Case 0:StartDateError=Test
        Case 1:EndDateError=Test
      EndSelect
      If Test
        SetActiveGadget(NoGadget)
      EndIf
  EndSelect
EndProcedure
;
If OpenWindow(0,0,0,120,65,"Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  StringGadget(0,10,10,100,20,"32/12/2024")
  StringGadget(1,10,35,100,20,"31/12/2024")
  BindGadgetEvent(0,@Pc_DateTypingControl())
  BindGadgetEvent(1,@Pc_DateTypingControl())
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
 
What do I do incorrectly? Thanks.

Win10-x64 - PB 6.11-x64

Re: StringGadgets, BingGadgetEvent, LostFocus and SetActiveGadget problem

Posted: Fri Sep 06, 2024 5:13 am
by TI-994A
boddhi wrote: Thu Sep 05, 2024 11:27 pm...the cursor disappears and it's impossible to bring it back...

The issue is most likely caused by setting focus events within the lost-focus event itself. It works well once the SetActiveGadget() function is called in queue, after the focus/lostFocus events have been processed, like this:

Code: Select all

EnableExplicit
; IMPORTANT: Dates must be in French format (DD/MM/YY or DD/MM/YYYY)
#setStringFocus = #PB_Event_FirstCustomValue
#REGEX_DATE=0
#DEFREGEX_DATEFORMAT="^(?:(?:31(\/|-|\.)(?:0?[13578]|1[02]))\1|(?:(?:29|30)(\/)(?:0?[13-9]|1[0-2])\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:29(\/)0?2\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\d|2[0-8])(\/)(?:(?:0?[1-9])|(?:1[0-2]))\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$"
CreateRegularExpression(#REGEX_DATE,#DEFREGEX_DATEFORMAT)
;
Procedure setStringFocus()
  SetActiveGadget(EventData())  
EndProcedure

Procedure   Pc_DateTypingControl()
  Protected.i Test
  Protected.u NoGadget=EventGadget(),NoEvenmt=EventType()
  Static.a StartDateError,EndDateError
  Static.s AncStartDate,AncEndDate,Date
  
  Select NoEvenmt
    Case #PB_EventType_Change
      ; [...]
    Case #PB_EventType_Focus ; Get the content of the gadget if no previous error
      Select NoGadget
          ; best to trim unintended spaces
          Case 0:If Not StartDateError:AncStartDate=Trim(GetGadgetText(0)):EndIf
          Case 1:If Not EndDateError:AncEndDate=Trim(GetGadgetText(1)):EndIf
      EndSelect
    Case #PB_EventType_LostFocus
      ; best to trim unintended spaces
      Date=Trim(GetGadgetText(NoGadget))
      Test=Bool(MatchRegularExpression(#REGEX_DATE,Date))!1
      Select NoGadget
        Case 0:StartDateError=Test
        Case 1:EndDateError=Test
      EndSelect
      If Test
        ;SetActiveGadget(NoGadget)        
        PostEvent(#setStringFocus, 0, #Null, #Null, NoGadget)
      EndIf
  EndSelect
EndProcedure
;
If OpenWindow(0,0,0,120,65,"Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  StringGadget(0,10,10,100,20,"32/12/2024")
  StringGadget(1,10,35,100,20,"31/12/2024")
  BindEvent(#setStringFocus, @setStringFocus())
  BindGadgetEvent(0,@Pc_DateTypingControl())
  BindGadgetEvent(1,@Pc_DateTypingControl())
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf

I'd also added Trim() functions to the string extractions to avoid inadvertent issues with spaces. :wink:

Re: StringGadgets, BingGadgetEvent, LostFocus and SetActiveGadget problem

Posted: Fri Sep 06, 2024 11:19 am
by boddhi
Hello TI-944,

Thanks for your tip. It works perfectly! :wink:
TI-994A wrote: I'd also added Trim() functions to the string extractions to avoid inadvertent issues with spaces. :wink:
Thanks. However, I plan to write a code that forbids the entry of any character other than numbers and '/' :wink: