Event handling with scrollbar

Just starting out? Need help? Post your questions and find answers here.
User avatar
kiwidave
User
User
Posts: 13
Joined: Sun Mar 09, 2014 9:27 am
Location: New Zealand

Event handling with scrollbar

Post by kiwidave »

Hi all,

I've just come across something interesting with the scrollbar gadget. It's a very simple scenario, there is an edit box on my form and a scrollbar (other stuff as well of course, but these are the only two of relevance here). I have some code in the LostFocus event for the edit box that writes the value into a variable. This works fine when the focus is lost by clicking on another gadget (i.e. a Save button or another field), but if I click on the Scrollbar, then the scrollbar event is fired first before the LostFocus event on the editbox. This is not desirable as the scrollbar event triggers a field refresh, so the field values are changed before the LostFocus takes effect, and therefore the LostFocus code is querying the wrong (refreshed) value. I've tried moving the event code around so that the scrollbar event is placed after the lostfocus event but this doesn't make any difference. Has anyone else come across this behaviour, and if so any ideas on how to prevent it?

Thank you.
Valui ad satanam in computatrum meum invocandum
User avatar
idle
Always Here
Always Here
Posts: 5836
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: Event handling with scrollbar

Post by idle »

maybe you should use an on change event for the edit box instead of lost focus to set your variable
Windows 11, Manjaro, Raspberry Pi OS
Image
User avatar
TI-994A
Addict
Addict
Posts: 2700
Joined: Sat Feb 19, 2011 3:47 am
Location: Singapore
Contact:

Re: Event handling with scrollbar

Post by TI-994A »

kiwidave wrote:...there is an edit box on my form and a scrollbar ... This works fine when the focus is lost by clicking on another gadget (i.e. a Save button or another field), but if I click on the Scrollbar, then the scrollbar event is fired first before the LostFocus event on the editbox. ...
Hello kiwidave. idle's suggestion to trap the #PB_EventType_Change event is quite preferable as the changes are tracked "real time". However, I can't seem to get a lost focus event by simply clicking on the ScrollBarGadget():

Code: Select all

wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
If OpenWindow(0, 0, 0, 200, 230, "Focus Events", wFlags)
  EditorGadget(1, 10, 10, 165, 90)
  StringGadget(2, 10, 105, 165, 90, "StringGadget()")
  ScrollBarGadget(3, 175, 10, 15, 185, 0, 100, 20, #PB_ScrollBar_Vertical)
  ButtonGadget(4, 10, 200, 180, 20, "Button")
  SetGadgetText(1, "EditorGadget()")
  Repeat
    Event = WaitWindowEvent()
    If Event = #PB_Event_Gadget
      Select EventGadget()
        Case 1, 2
          Select EventType()
            Case #PB_EventType_Focus
              Debug "Gadget #:" + EventGadget() + " got focus"
            Case #PB_EventType_LostFocus
              Debug "Gadget #:" + EventGadget() + " lost focus"
          EndSelect
        Case 3
          Debug "ScrollBar event..."
      EndSelect
    EndIf
  Until Event = #PB_Event_CloseWindow
EndIf
Perhaps you have extended the event handler for the ScrollBarGadget()?
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
User avatar
kiwidave
User
User
Posts: 13
Joined: Sun Mar 09, 2014 9:27 am
Location: New Zealand

Re: Event handling with scrollbar

Post by kiwidave »

TI-994A wrote:Hello kiwidave. idle's suggestion to trap the #PB_EventType_Change event is quite preferable as the changes are tracked "real time". However, I can't seem to get a lost focus event by simply clicking on the ScrollBarGadget()
Thank you TI-994A, your example is exactly what I'm seeing - clicking from either of the edit or string boxes to the scrollbar doesn't fire the lostfocus event. The fact that I am seeing a subsequent lostfocus being fired may be something to do with the fact that on my scrollbar event I do a pile of gadget manipulation, but this is not of a concern at the moment.

I would suggest that this is a bug in that case. I was trying to avoid using #PB_EventType_Change as suggested by idle simply because it incurs unnecessary system overhead for what I am wanting to achieve, but given your example confirming the behaviour, I think I will need to go down this path.
Valui ad satanam in computatrum meum invocandum
User avatar
Danilo
Addict
Addict
Posts: 3036
Joined: Sat Apr 26, 2003 8:26 am
Location: Planet Earth

Re: Event handling with scrollbar

Post by Danilo »

@kiwidave:
What happens on your OS when you use BindGadgetEvent()?

Code: Select all

Procedure OnGotFocus()
    Debug "Gadget #:" + EventGadget() + " got focus"
EndProcedure

Procedure OnLostFocus()
    Debug "Gadget #:" + EventGadget() + " lost focus"
EndProcedure

Procedure OnScroll()
    Debug "ScrollBar event..."
EndProcedure

Procedure OnClose()
    End
EndProcedure

wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
If OpenWindow(0, 0, 0, 200, 230, "Focus Events", wFlags)
  EditorGadget(1, 10, 10, 165, 90)
  StringGadget(2, 10, 105, 165, 90, "StringGadget()")
  ScrollBarGadget(3, 175, 10, 15, 185, 0, 100, 20, #PB_ScrollBar_Vertical)
  ButtonGadget(4, 10, 200, 180, 20, "Button")
  SetGadgetText(1, "EditorGadget()")
  
  BindGadgetEvent(1,@OnGotFocus() ,#PB_EventType_Focus)
  BindGadgetEvent(1,@OnLostFocus(),#PB_EventType_LostFocus)
  
  BindGadgetEvent(2,@OnGotFocus() ,#PB_EventType_Focus)
  BindGadgetEvent(2,@OnLostFocus(),#PB_EventType_LostFocus)
  
  BindGadgetEvent(3,@OnScroll())
  
  BindEvent(#PB_Event_CloseWindow,@OnClose(),0)
  
  While WaitWindowEvent(): Wend
EndIf
The old event system had some problems with real-time event handling, for example with ScrollbarGadget(),
and also window resize and such things. That's why it has been replaced with the new system using Bind(Gadget)Event, PostEvent, etc.

On Windows, the OS bypasses the ordinary event queue for some real-time events. It calls directly
the event handler of the specific control, so it also bypasses the PureBasic event handling. That's the problem.

In your special case you could simply do:

Code: Select all

Procedure OnScroll()
    If GetActiveGadget()=1
        ; save your values
        Debug "values saved"
    EndIf
    ; more processing
    Debug "ScrollBar event..."
EndProcedure
Post Reply