Page 1 of 1

Generating LostFocus events from SpinGadgets

Posted: Wed Aug 26, 2015 7:28 am
by BasicallyPure
For Windows only.
This is a way to get #PB_EventType_LostFocus events from spin gadgets.
Caution, it will not work if the spin gadget was created using #PB_Any.
It seems the gadget numbers are too large to fit in the Low word of wParam.

Code: Select all

; generate LostFocus events from spin gadgets

#WinMain = 0

Procedure WIN_CALLBACK(hWnd, uMsg, wParam, lParam)
   ; Window callback to generate LostFocus events for spin gadgets
   Protected gadget
   
   Select uMsg
      Case #WM_COMMAND
         Select wParam >> 16 ; get HiWord
            Case #EN_KILLFOCUS
               gadget = wParam & $FFFF ; get LoWord
               If GadgetType(gadget) = #PB_GadgetType_Spin
                  PostEvent(#PB_Event_Gadget, #WinMain, gadget, #PB_EventType_LostFocus)
               EndIf
         EndSelect
   EndSelect
    
   ProcedureReturn #PB_ProcessPureBasicEvents
EndProcedure

If OpenWindow(#WinMain,0,0,400,250,"Spin gadget LostFocus events",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
   SetWindowCallback(@WIN_CALLBACK(),#WinMain)
   
   SpinGadget(1,10,010,100,25,0,9999,#PB_Spin_Numeric) : SetGadgetText(1,"0")
   SpinGadget(2,10,060,100,25,0,9999,#PB_Spin_Numeric) : SetGadgetText(2,"0")
   SpinGadget(3,10,110,100,25,0,9999,#PB_Spin_Numeric) : SetGadgetText(3,"0")
   SpinGadget(4,10,160,100,25,0,9999,#PB_Spin_Numeric) : SetGadgetText(4,"0")
   
   ButtonGadget(#PB_Any,150,010,100,25,"1")
   ButtonGadget(#PB_Any,150,060,100,25,"2")
   ButtonGadget(#PB_Any,150,110,100,25,"3")
   ButtonGadget(#PB_Any,150,160,100,25,"4")
   
   CheckBoxGadget(#PB_Any,300,010,50,25,"1")
   CheckBoxGadget(#PB_Any,300,060,50,25,"2")
   CheckBoxGadget(#PB_Any,300,110,50,25,"3")
   CheckBoxGadget(#PB_Any,300,160,50,25,"4")
   
   Repeat
      Select WaitWindowEvent()
         Case #PB_Event_Gadget
            If EventType() = #PB_EventType_LostFocus
               Select EventGadget()
                  Case 1 : Debug "spin_1 lost focus"
                  Case 2 : Debug "spin_2 lost focus"
                  Case 3 : Debug "spin_3 lost focus"
                  Case 4 : Debug "spin_4 lost focus"
               EndSelect
            EndIf
         Case #PB_Event_CloseWindow
            exit = #True
      EndSelect
   Until exit
   
EndIf

Re: Generating LostFocus events from SpinGadgets

Posted: Wed Aug 26, 2015 6:31 pm
by RASHAD
- Cross platform
- Can use #PB_Any

Code: Select all

#WinMain = 0

If OpenWindow(#WinMain,0,0,400,250,"Spin gadget LostFocus events",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
   
   sp1=SpinGadget(#PB_Any,10,010,100,25,0,9999,#PB_Spin_Numeric) : SetGadgetText(sp1,"0") :SetGadgetData(sp1,1)
   sp2=SpinGadget(#PB_Any,10,060,100,25,0,9999,#PB_Spin_Numeric) : SetGadgetText(sp2,"0") :SetGadgetData(sp2,2)
   sp3=SpinGadget(#PB_Any,10,110,100,25,0,9999,#PB_Spin_Numeric) : SetGadgetText(sp3,"0") :SetGadgetData(sp3,3)
   sp4=SpinGadget(#PB_Any,10,160,100,25,0,9999,#PB_Spin_Numeric) : SetGadgetText(sp4,"0") :SetGadgetData(sp4,4)
   
   ButtonGadget(#PB_Any,150,010,100,25,"1")
   ButtonGadget(#PB_Any,150,060,100,25,"2")
   ButtonGadget(#PB_Any,150,110,100,25,"3")
   ButtonGadget(#PB_Any,150,160,100,25,"4")
   
   CheckBoxGadget(#PB_Any,300,010,50,25,"1")
   CheckBoxGadget(#PB_Any,300,060,50,25,"2")
   CheckBoxGadget(#PB_Any,300,110,50,25,"3")
   CheckBoxGadget(#PB_Any,300,160,50,25,"4")
   
   Repeat
      Select WaitWindowEvent()
         Case #PB_Event_Gadget
            Select EventType()
                Case #PB_EventType_Change
                    If GadgetType(GetActiveGadget()) = #PB_GadgetType_Spin
                       gad = GetActiveGadget()         
                       Debug "Gadget : "+Str(gad)+"  Gadget # : "+Str(GetGadgetData(gad))+"  got the focus" 
                    EndIf
                    
                Case #PB_EventType_LeftClick
                    Debug "Spin Gadget lost focus"             
                    
            EndSelect
            
         Case #PB_Event_CloseWindow
            exit = #True
      EndSelect
   Until exit
   
EndIf


Re: Generating LostFocus events from SpinGadgets

Posted: Wed Aug 26, 2015 8:40 pm
by BasicallyPure
@Rashad
No that doesn't work.
1. We need to know which gadget lost focus.
2. No lost focus event is reported when switching to another spin gadget.
(or any gadget that does not produce #PB_EventType_LeftClick events.)
3. No lost focus event when using Tab to move between gadgets.

Re: Generating LostFocus events from SpinGadgets

Posted: Sun Aug 30, 2015 10:01 am
by Vera
How about doing it this way ?
It should serve all above mentioned needs, allow #PB_Any and be crossplatform.

Code: Select all

Enumeration
  #WinMain
EndEnumeration
Enumeration 1 Step 1    ; for to have a "1" in the first SpinGadget
  #sp1
  #sp2
  #sp3
  #sp4
EndEnumeration

choosePB_Any = #False       ; 0/1 for quick selection

Global   setFocus = #False
Global.i  newFocus, oldFocus

Procedure checkSpinFocus(event)
  
  If event And GadgetType(GetActiveGadget()) = #PB_GadgetType_Spin
    newFocus = GetActiveGadget() ; : Debug "newFocus " + Str(newFocus)
    If setFocus
      If oldFocus <> newFocus
        Debug "a lost focus: " + Str(oldFocus)
      EndIf
    EndIf
    oldFocus = newFocus : setFocus = #True 
    
  ElseIf event And GadgetType(GetActiveGadget()) <> #PB_GadgetType_Spin
    If setFocus = #True
      Debug "b lost focus: " + Str(oldFocus)
      setFocus = #False
    EndIf
    
  EndIf
EndProcedure


If OpenWindow(#WinMain, 0,0, 400,250, "Spin gadget LostFocus events", #PB_Window_ScreenCentered |#PB_Window_SystemMenu)
  
  If Not choosePB_Any
  SpinGadget(#sp1, 10,010, 100,25, 0, 99,#PB_Spin_Numeric) : SetGadgetText(#sp1,"1")
  SpinGadget(#sp2, 10,060, 100,25, 0, 99,#PB_Spin_Numeric) : SetGadgetText(#sp2,"2")
  SpinGadget(#sp3, 10,110, 100,25, 0, 99,#PB_Spin_Numeric) : SetGadgetText(#sp3,"3")
  SpinGadget(#sp4, 10,160, 100,25, 0, 99,#PB_Spin_Numeric) : SetGadgetText(#sp4,"4")
  Else
  sp1=SpinGadget(#PB_Any, 10,010, 100,25, 0, 99,#PB_Spin_Numeric) : SetGadgetText(sp1, Str(sp1))
  sp2=SpinGadget(#PB_Any, 10,060, 100,25, 0, 99,#PB_Spin_Numeric) : SetGadgetText(sp2, Str(sp2))
  sp3=SpinGadget(#PB_Any, 10,110, 100,25, 0, 99,#PB_Spin_Numeric) : SetGadgetText(sp3, Str(sp3))
  sp4=SpinGadget(#PB_Any, 10,160, 100,25, 0, 99,#PB_Spin_Numeric) : SetGadgetText(sp4, Str(sp4))
  EndIf

  ButtonGadget(#PB_Any, 150,010, 100,25, "1")
  ButtonGadget(#PB_Any, 150,060, 100,25, "2")
  ButtonGadget(#PB_Any, 150,110, 100,25, "3")
  ButtonGadget(#PB_Any, 150,160, 100,25, "4")
  
  CheckBoxGadget(#PB_Any, 300,010, 50,25, "1")
  CheckBoxGadget(#PB_Any, 300,060, 50,25, "2")
  CheckBoxGadget(#PB_Any, 300,110, 50,25, "3")
  CheckBoxGadget(#PB_Any, 300,160, 50,25, "4")
  
    
  Repeat
    event = WaitWindowEvent()
    
    If GetActiveGadget() > -1
      checkSpinFocus(event)
    EndIf
    
    Select event
      Case #PB_Event_Gadget
        Select EventType()
          Case #PB_EventType_Change 
            If choosePB_Any                ; for to keep the ID visible
              SetGadgetText(EventGadget(), Str(EventGadget()))
            EndIf
          Case #PB_EventType_LeftClick
        EndSelect
        
      Case #PB_Event_CloseWindow
        exit = #True
    EndSelect
  Until exit
  
EndIf

Re: Generating LostFocus events from SpinGadgets

Posted: Mon Aug 31, 2015 3:55 am
by BasicallyPure
Thank you Vera, that works very well.

I changed the checkSpinFocus() procedure to eliminate the need for global variables.
I changed variable names to make the logic a little easier to follow (for me).
Also added PostEvent to generate #PB_EventType_LostFocus events.

I've only tested on Windows so far, but it looks like it should work on all platforms.

thanks again. :)

, Edit: 8/31/15

Code: Select all

I changed 
WaitWindowEvent(10)
to
WaitWindowEvent()
I was testing something and I forgot to change it back.
Here is the updated code.

Code: Select all

#WinMain = 0

Enumeration 1  ; for to have a "1" in the first SpinGadget
   #sp1 : #sp2 : #sp3 : #sp4
EndEnumeration

choosePB_Any = #True  ; 0/1 For quick selection

Procedure checkSpinFocus(event)
   Static lastSpinGadget, lastGadgetWasSpin
   Protected thisGadget = GetActiveGadget()
   
   If GadgetType(thisGadget) = #PB_GadgetType_Spin
      If lastGadgetWasSpin = #True
         If lastSpinGadget <> thisGadget ;focus has moved between spin gadgets
            PostEvent(#PB_Event_Gadget,GetActiveWindow(),lastSpinGadget,#PB_EventType_LostFocus)
         EndIf
      Else
         lastGadgetWasSpin = #True
      EndIf
      lastSpinGadget = thisGadget
   ElseIf lastGadgetWasSpin = #True ;focus moved from spin gadget to another gadget type
      PostEvent(#PB_Event_Gadget,GetActiveWindow(),lastSpinGadget,#PB_EventType_LostFocus)
      lastGadgetWasSpin = #False
   EndIf
   
EndProcedure


If OpenWindow(#WinMain, 0,0, 400,250, "Spin gadget LostFocus events", #PB_Window_ScreenCentered |#PB_Window_SystemMenu)
   
   If choosePB_Any
      sp1=SpinGadget(#PB_Any, 10,010, 100,25, 0, 99,#PB_Spin_ReadOnly) : SetGadgetText(sp1, Str(sp1))
      sp2=SpinGadget(#PB_Any, 10,060, 100,25, 0, 99,#PB_Spin_ReadOnly) : SetGadgetText(sp2, Str(sp2))
      sp3=SpinGadget(#PB_Any, 10,110, 100,25, 0, 99,#PB_Spin_ReadOnly) : SetGadgetText(sp3, Str(sp3))
      sp4=SpinGadget(#PB_Any, 10,160, 100,25, 0, 99,#PB_Spin_ReadOnly) : SetGadgetText(sp4, Str(sp4))
   Else
      SpinGadget(#sp1, 10,010, 100,25, 0, 99,#PB_Spin_ReadOnly) : SetGadgetText(#sp1, "1")
      SpinGadget(#sp2, 10,060, 100,25, 0, 99,#PB_Spin_ReadOnly) : SetGadgetText(#sp2, "2")
      SpinGadget(#sp3, 10,110, 100,25, 0, 99,#PB_Spin_ReadOnly) : SetGadgetText(#sp3, "3")
      SpinGadget(#sp4, 10,160, 100,25, 0, 99,#PB_Spin_ReadOnly) : SetGadgetText(#sp4, "4")
   EndIf
   
   For y = 10 To 160 Step 50
      ButtonGadget(#PB_Any  , 150,y, 100,25, Str(1+y/50))
      CheckBoxGadget(#PB_Any, 300,y, 050,25, Str(1+y/50))
   Next y
   
   Repeat
      event = WaitWindowEvent()
      
      If event And GetActiveGadget() > -1
         checkSpinFocus(event)
      EndIf
      
      Select event
         Case #PB_Event_Gadget
            Select EventGadget()
               Case sp1,sp2,sp3,sp4,#sp1,#sp2,#sp3,#sp4
                  If EventType() = #PB_EventType_LostFocus
                     Debug "spin " + Str(EventGadget()) + " lost focus"
                  EndIf
            EndSelect
         Case #PB_Event_CloseWindow
            exit = #True
      EndSelect
   Until exit
   
EndIf

Re: Generating LostFocus events from SpinGadgets

Posted: Mon Aug 31, 2015 12:42 pm
by Vera
Hey that's great and nice to hear :-)

That logic had been nagging on my brain for two days and I was worried about the additional high amount of checks.

And dito thanks for your enhancements (&indirect hints) and updating it to PB > 5.1x.
It'll be a helpul example when I'll start moving my codes to 5.40 ... soon.

Image ~ Vera