Page 1 of 1

Event focus of new window

Posted: Sat Feb 01, 2014 7:23 pm
by longwave
I have a main OpenWindow(#Window_0...) that has a title bar with one item. Clicking on the menu item calls a Procedure that opens a second OpenWindow(#Window_1). #Window_1 does not have #Window_0 as it's parent as I am wanting to minimize #Window_0 and have #Window_1 left on the screen for display. The problem I am having is that all the events now are associated with #Window_1 when it opens. If I click on #Window_0 and click on a gadget nothing happens. How can events be detected in both windows ?

Re: Event focus of new window

Posted: Sat Feb 01, 2014 8:47 pm
by Sparkie
No problems here with that scenario. Got code?

Re: Event focus of new window

Posted: Sun Feb 02, 2014 1:44 am
by netmaestro
Couple notes on using multiple windows:

-Gadget numbers may not be reused on a new window if your original window is still using them. If your window_0 uses gadgets with numbers 0-11, you would need to start at 12 or more for gadgets placed on a second window. Otherwise your window_0 gadgets will disappear on you.

-When checking for window events you must use EventWindow() if you're using an event loop, this way you can know what window fired the event. An alternative is to use BindEvent(@callback1(), window_0) and BindEvent(@callback2(), window_1). EventGadget() will give you the gadget and they're all unique.

Keeping these ideas in mind, see if you can fix your code to work as expected. If not, post it here as Sparkie suggests and someone will lend a hand.

Re: Event focus of new window

Posted: Sun Feb 02, 2014 3:53 am
by PB
Practical example of what NetMaestro means:

Code: Select all

OpenWindow(1,20,20,260,70,"win 1",#PB_Window_SystemMenu)
  ButtonGadget(1,20,20,100,30,"win 1 / gadget 1")
  ButtonGadget(2,140,20,100,30,"win 1 / gadget 2")

OpenWindow(2,310,20,260,70,"win 2",#PB_Window_SystemMenu)
  ButtonGadget(3,20,20,100,30,"win 2 / gadget 3")
  ButtonGadget(4,140,20,100,30,"win 2 / gadget 4")

Repeat

  ev=WaitWindowEvent()

  If ev=#PB_Event_Gadget

    w=EventWindow()
    g=EventGadget()

    Debug "window = "+Str(w)+" / gadget = "+Str(g)

  EndIf

Until ev=#PB_Event_CloseWindow

Re: Event focus of new window

Posted: Sun Feb 02, 2014 7:15 pm
by longwave
Using your example this is what I am trying to do.

Code: Select all

Enumeration
  #Window_1
  #Window_2
  #Menu_1
  #Button_1
  #Button_2
  #Button_3
  #Button_4
EndEnumeration

Declare window_2()

Procedure window_1()
  OpenWindow(#Window_1,20,20,260,90,"win 1",#PB_Window_SystemMenu | #PB_Window_MinimizeGadget)
  CreateMenu(#Menu_1, WindowID(#Window_1))
      MenuTitle("Menu")
        MenuItem(1, "Open Window_2")
  ButtonGadget(#Button_1,20,20,100,30,"win 1 / gadget 1")
  ButtonGadget(#Button_2,140,20,100,30,"win 1 / gadget 2")
EndProcedure

Procedure window_2()
  OpenWindow(#Window_2,310,20,260,70,"win 2",#PB_Window_SystemMenu | #PB_Window_MinimizeGadget)
  ButtonGadget(#Button_3,20,20,100,30,"win 2 / gadget 3")
  ButtonGadget(#Button_4,140,20,100,30,"win 2 / gadget 4")  
  Repeat   
  event = WaitWindowEvent()
  Select event
    Case #PB_Event_Gadget
      Select EventGadget()
        Case #Button_3
          Debug "win 2 / gadget 3"
        Case #Button_4
          Debug "win 2 / gadget 4"
      EndSelect
  EndSelect
  Until Event = #PB_Event_CloseWindow
  CloseWindow(#Window_2)
  EndProcedure
  
  ; Run
  
  window_1()
  Repeat
  event = WaitWindowEvent()
  Select event
    Case #PB_Event_Gadget
       Select EventGadget()
         Case #Button_1
           Debug "win 1 / gadget 1"
         Case #Button_2
           Debug "win 1 / gadget 2"
       EndSelect
    Case  #PB_Event_Menu
      Select EventMenu() 
        Case 1
          window_2()
      EndSelect
  EndSelect
  Until Event = #PB_Event_CloseWindow
  End

Re: Event focus of new window

Posted: Sun Feb 02, 2014 8:05 pm
by Sparkie
Notice there is only one event loop now to handle all messages for both windows.

Code: Select all

Enumeration
  #Window_1
  #Window_2
  #Menu_1
  #Button_1
  #Button_2
  #Button_3
  #Button_4
EndEnumeration

Declare window_2()

Procedure window_1()
  OpenWindow(#Window_1,20,20,260,90,"win 1",#PB_Window_SystemMenu | #PB_Window_MinimizeGadget)
  CreateMenu(#Menu_1, WindowID(#Window_1))
      MenuTitle("Menu")
        MenuItem(1, "Open Window_2")
  ButtonGadget(#Button_1,20,20,100,30,"win 1 / gadget 1")
  ButtonGadget(#Button_2,140,20,100,30,"win 1 / gadget 2")
EndProcedure

Procedure window_2()
  OpenWindow(#Window_2,310,20,260,70,"win 2",#PB_Window_SystemMenu | #PB_Window_MinimizeGadget)
  ButtonGadget(#Button_3,20,20,100,30,"win 2 / gadget 3")
  ButtonGadget(#Button_4,140,20,100,30,"win 2 / gadget 4")  
EndProcedure
  
  ; Run
  
  window_1()
  quit = #False
  Repeat
  event = WaitWindowEvent()
  Select event
    Case #PB_Event_Gadget
       Select EventGadget()
         Case #Button_1
           Debug "win 1 / gadget 1"
         Case #Button_2
           Debug "win 1 / gadget 2"
           Case #Button_3
          Debug "win 2 / gadget 3"
        Case #Button_4
          Debug "win 2 / gadget 4"
       EndSelect
    Case  #PB_Event_Menu
      Select EventMenu() 
        Case 1
          window_2()
      EndSelect
    Case #PB_Event_CloseWindow
      Select EventWindow()
        Case #Window_2
          CloseWindow(#Window_2)
        Case #Window_1
          quit = #True
      EndSelect
      
  EndSelect
  Until quit
  End

Re: Event focus of new window

Posted: Sun Feb 02, 2014 8:58 pm
by longwave
In Procedure window_2() there is a Repeat, Until loop. I do not see it in your copy though.

Re: Event focus of new window

Posted: Sun Feb 02, 2014 8:59 pm
by netmaestro
In window_2 there is a repeat, until loop. I do not see it in your copy though.
Sparkie shows the correct way to handle events for multiple windows. More than one event loop in a program is a recipe for problems. Notice his 'Select EventWindow()' block.

Re: Event focus of new window

Posted: Sun Feb 02, 2014 9:03 pm
by davido
netmaestro wrote:Sparkie shows the correct way to handle events for multiple windows. More than one event loop in a program is a recipe for problems. Notice his 'Select EventWindow()' block.
Isn't BindEvent(0) a possible alternative?

Re: Event focus of new window

Posted: Sun Feb 02, 2014 9:07 pm
by longwave
I was trying to delete my response as I did not index all the way down his code. Just noticed the missing Repeat, Untill on Procedure window_2() in his reply. Thanks for the help. This clears up my thoughts on how to proceed.

Re: Event focus of new window

Posted: Sun Feb 02, 2014 9:18 pm
by netmaestro
Isn't BindEvent(0) a possible alternative?
BindEvent is for specific events. You can certainly use it (and it's an excellent alternative, even superior) but you have to bind each event individually. There is no #PB_All support for the Event parameter of BindEvent. This is not a real problem as most programs only want to handle three or four window events anyway. Code written in this way is nicely structured and very maintainable. A big advantage is you get real-time events for things like scrolllbars moving and such, and a really useful one, #PB_Event_Repaint. Here's a hands-on example of what I mean:

Try this code and drag the window half off the screen. As you drag it back and the window begins to repaint itself, you get none of these events in realtime. Drag it all the way to the middle of the screen, nothing. Then let go of it and they all happen at once.

Now, uncomment the first block of code and comment the second one. Here we're using BindEvent and the result is much better. As you drag the window back onto the screen you can watch the proc catching every paint.

Code: Select all

; Procedure winproc()
;   Debug "Painting"
; EndProcedure
; 
; OpenWindow(0,0,0,320,240,"")
; BindEvent(#PB_Event_Repaint, @winproc())
; 
; Repeat:Until WaitWindowEvent() = #PB_Event_CloseWindow


OpenWindow(0,0,0,320,240,"")

Repeat: eventid = WaitWindowEvent() 
  If eventid = #PB_Event_Repaint
    Debug "Painting"
  EndIf
 Until eventid = #PB_Event_CloseWindow

Re: Event focus of new window

Posted: Sun Feb 02, 2014 9:34 pm
by netmaestro
For fun, here is the Sparkie code converted for BindEvent():

Code: Select all

Enumeration
  #Window_1
  #Window_2
  #Menu_1
  #Button_1
  #Button_2
  #Button_3
  #Button_4
EndEnumeration

Declare window_2()

Procedure window_1()
  OpenWindow(#Window_1,20,20,260,90,"win 1",#PB_Window_SystemMenu | #PB_Window_MinimizeGadget)
  CreateMenu(#Menu_1, WindowID(#Window_1))
  MenuTitle("Menu")
  MenuItem(1, "Open Window_2")
  ButtonGadget(#Button_1,20,20,100,30,"win 1 / gadget 1")
  ButtonGadget(#Button_2,140,20,100,30,"win 1 / gadget 2")
EndProcedure

Procedure window_2()
  OpenWindow(#Window_2,310,20,260,70,"win 2",#PB_Window_SystemMenu | #PB_Window_MinimizeGadget)
  ButtonGadget(#Button_3,20,20,100,30,"win 2 / gadget 3")
  ButtonGadget(#Button_4,140,20,100,30,"win 2 / gadget 4")  
EndProcedure

Procedure GadgetProc()
  Select EventGadget()
    Case #Button_1
      Debug "win 1 / gadget 1"
    Case #Button_2
      Debug "win 1 / gadget 2"
    Case #Button_3
      Debug "win 2 / gadget 3"
    Case #Button_4
      Debug "win 2 / gadget 4"
  EndSelect
EndProcedure

Procedure MenuProc()
  Select EventMenu() 
    Case 1
      window_2()
  EndSelect
EndProcedure

Procedure CloseProc()
  CloseWindow( EventWindow())
EndProcedure

BindEvent(#PB_Event_Gadget, @GadgetProc())
BindEvent(#PB_Event_Menu, @menuProc())
BindEvent(#PB_Event_CloseWindow, @CloseProc())

; Run

window_1()
Repeat : WaitWindowEvent() : Until IsWindow(#Window_1) = 0

Re: Event focus of new window

Posted: Sun Feb 02, 2014 11:29 pm
by davido
@netmaestro

Thank you very much. :D

Very nice couple of demonstrations.