Post event and canvas

Just starting out? Need help? Post your questions and find answers here.
mestnyi
Addict
Addict
Posts: 995
Joined: Mon Nov 25, 2013 6:41 am

Post event and canvas

Post by mestnyi »

There are strange things.
If you specify the ID of the create gadget, an error occurs

Code: Select all

wg::Create(2,30,30,100,100)
otherwise there is no

Code: Select all

wg::Create(-1,30,30,100,100)
So I think it's a bug.

Code: Select all

DeclareModule wg
  Declare Create(Gadget, X,Y,Width,Height, Title$="", Flag=0, Parent=-1)
EndDeclareModule

Module wg
  Structure WindowStruct
    Parent.i
    Gadget.i
  EndStructure
  
  Procedure ParentCallBack()
    Static OffsetX, OffsetY
    Protected Gadget = EventGadget()
    Protected *wg.WindowStruct = GetGadgetData(Gadget)
    
    With *wg
      Select EventType()
        Case #PB_EventType_MouseMove
          Debug GetGadgetAttribute(Gadget, #PB_Canvas_MouseX) 
          
      EndSelect
    EndWith
  EndProcedure
  
  Procedure CallBack()
    Protected Gadget = EventGadget()
    Protected *wg.WindowStruct = GetGadgetData(Gadget)
    ; PostEvent(#PB_Event_Gadget, EventWindow(), *wg\Parent, EventType()) ; good uncomment to see
    ; PostEvent(#PB_Event_Gadget, EventWindow(), *wg\Parent, EventType(), *wg) ; good uncomment to see
    PostEvent(#PB_Event_Gadget, EventWindow(), *wg\Parent, EventType(), Gadget ) ; Bug? uncomment to see
  EndProcedure
  
  Procedure Create(Gadget, X,Y,Width,Height, Title$="", Flag=0, Parent=-1)
    Protected *wg.WindowStruct = AllocateStructure(WindowStruct)
    
    With *wg
      \Parent = CanvasGadget(#PB_Any, x,y, Width,Height) 
      
      \Gadget = CanvasGadget(Gadget, x+Width+10,y, Width,Height ) 
      If IsGadget(Gadget) : \Gadget = Gadget : EndIf
      
      SetGadgetData(\Parent, *wg)
      SetGadgetData(\Gadget, *wg)
      
      BindGadgetEvent(\Parent, @ParentCallBack())
      BindGadgetEvent(\Gadget, @CallBack(), #PB_EventType_MouseMove)
      
      ProcedureReturn \Gadget
    EndWith
  EndProcedure
  
  
EndModule

;- Example
CompilerIf #PB_Compiler_IsMainFile
  Enumeration
    #Window
  EndEnumeration
  
  Procedure OpenWindow_0()
    OpenWindow(#Window, 0, 0, 600, 400, "WindowTitle",
               #PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
    
    wg::Create(2,30,30,100,100)
    
  EndProcedure
  
  OpenWindow_0()
  
  Repeat
    
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        End
    EndSelect
    
  ForEver
CompilerEndIf
Last edited by mestnyi on Mon Nov 20, 2017 6:06 pm, edited 1 time in total.
bosker
Enthusiast
Enthusiast
Posts: 105
Joined: Fri Jan 08, 2010 11:04 pm
Location: Hampshire, UK

Re: Post event and canvas

Post by bosker »

In your ParentCallback function, should the line...

Code: Select all

Debug GetGadgetAttribute(Gadget, #PB_Canvas_MouseX)
..actually be...

Code: Select all

Debug GetGadgetAttribute(\Gadget, #PB_Canvas_MouseX)
The memory failure goes away with this change.
#NULL
Addict
Addict
Posts: 1440
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: Post event and canvas

Post by #NULL »

@Bosker: Gadget is the Protected Variable from EventGadget() which is correct i think.

but this is wrong:

Code: Select all

      \Gadget = CanvasGadget(Gadget, x+Width+10,y, Width,Height )
      If IsGadget(Gadget) : \Gadget = Gadget : EndIf
- You are checking in IsGadget() with the local Variable instead of the return value of CanvasGadget(). should be something like this instead:

Code: Select all

      Gadget = CanvasGadget(Gadget, x+Width+10,y, Width,Height )
      If IsGadget(Gadget) : \Gadget = Gadget : EndIf
- If you use 'wg::Create(2, ...' then the return value of CanvasGadget() will be a GadgetID, not a #Gadget number.
And..
- If you use 'wg::Create(-1, ...' then the return value of CanvasGadget() will be a #Gadget number, not a GadgetID.
you have to be aware fo that.

- In any case you should use #PB_Any instead of -1, at least for the PB Commands themself, but thats not a problem here i think.

- You should check the return value of CanvasGadget() only for zero/non-zero. If it fails and returns 0, then IsGadget(0) will pass fine if you used that static Gadget number elsewhere.
#NULL
Addict
Addict
Posts: 1440
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: Post event and canvas

Post by #NULL »

I added the the handling of the return value of CanvasGadget(). But i'm not sure what you want to do with the PostEvents. Do you want to notify the \Parent if the \Gadget receives a mouse move?

Code: Select all

DeclareModule wg
  Declare Create(Gadget, X,Y,Width,Height, Title$="", Flag=0, Parent=-1)
EndDeclareModule

Module wg
  Structure WindowStruct
    Parent.i
    Gadget.i
  EndStructure
 
  Procedure ParentCallBack()
    Static OffsetX, OffsetY
    Protected Gadget = EventGadget()
    Protected *wg.WindowStruct = GetGadgetData(Gadget)
    
    With *wg
      Select EventType()
        Case #PB_EventType_MouseMove
;           Debug "EventGadget(): " + EventGadget()
;           Debug "Gadget: " + Gadget
;           Debug "*wg\Parent: " + *wg\Parent
;           Debug "*wg\Gadget: " + *wg\Gadget
          Debug "parent mouse: " + GetGadgetAttribute(Gadget, #PB_Canvas_MouseX)
         
      EndSelect
    EndWith
  EndProcedure
 
  Procedure CallBack()
    Protected Gadget = EventGadget()
    Protected *wg.WindowStruct = GetGadgetData(Gadget)
;     PostEvent(#PB_Event_Gadget, EventWindow(), *wg\Parent, EventType()) ; good uncomment to see
;     PostEvent(#PB_Event_Gadget, EventWindow(), *wg\Parent, EventType(), Gadget) ; Bug? uncomment to see
    PostEvent(#PB_Event_Gadget, EventWindow(), *wg\Parent, EventType(), *wg\Parent)
  EndProcedure
 
  Procedure Create(Gadget, X,Y,Width,Height, Title$="", Flag=0, Parent=-1)
    Protected *wg.WindowStruct = AllocateStructure(WindowStruct)
    
;     Debug SizeOf(WindowStruct)
;     Debug SizeOf(*wg)
    
    With *wg
      \Parent = CanvasGadget(#PB_Any, x,y, Width,Height)
      
      ;\Gadget = CanvasGadget(Gadget, x+Width+10,y, Width,Height )
      ;If IsGadget(Gadget) : \Gadget = Gadget : EndIf
      
      Protected result
      result = CanvasGadget(Gadget, x+Width+10,y, Width,Height )
      If result
        If Gadget = #PB_Any
          \Gadget = result
        Else
          \Gadget = Gadget
        EndIf
      EndIf
      
      Debug "\Parent: " + \Parent
      Debug "\Gadget: " + \Gadget
      
      SetGadgetData(\Parent, *wg)
      SetGadgetData(\Gadget, *wg)
      
      BindGadgetEvent(\Parent, @ParentCallBack());, #PB_Event_Gadget)
      BindGadgetEvent(\Gadget, @CallBack(), #PB_EventType_MouseMove)
     
      ProcedureReturn \Gadget
    EndWith
  EndProcedure
 
 
EndModule

;- Example
CompilerIf #PB_Compiler_IsMainFile
  Enumeration
    #Window
  EndEnumeration
 
  Procedure OpenWindow_0()
    OpenWindow(#Window, 0, 0, 600, 400, "WindowTitle",
               #PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
   
    wg::Create(2,30,30,100,100)
    ;wg::Create(#PB_Any,30,230,100,100)
   
  EndProcedure
 
  OpenWindow_0()
 
  Repeat
   
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        End
    EndSelect
   
  ForEver
CompilerEndIf
mestnyi
Addict
Addict
Posts: 995
Joined: Mon Nov 25, 2013 6:41 am

Re: Post event and canvas

Post by mestnyi »

Why is this wrong? :shock:

Code: Select all

\Gadget = CanvasGadget(Gadget, x+Width+10,y, Width,Height )
          If IsGadget(Gadget) 
              \Gadget = Gadget 
          EndIf
Look at my code and yours. What is pure? When the result is the same.

Code: Select all

result = CanvasGadget(Gadget, x+Width+10,y, Width,Height )
      If result
        If Gadget = #PB_Any
          \Gadget = result
        Else
          \Gadget = Gadget
        EndIf
      EndIf
And in general a problem in it

Code: Select all

PostEvent(#PB_Event_Gadget, EventWindow(), *wg\Parent, EventType()) ; good uncomment to see
     PostEvent(#PB_Event_Gadget, EventWindow(), *wg\Parent, EventType(), Gadget) ; Bug? uncomment to see
bosker wrote:In your ParentCallback function, should the line...

Code: Select all

Debug GetGadgetAttribute(Gadget, #PB_Canvas_MouseX)
..actually be...

Code: Select all

Debug GetGadgetAttribute(\Gadget, #PB_Canvas_MouseX)
The memory failure goes away with this change.
And why is it not happening?

Code: Select all

PostEvent(#PB_Event_Gadget, EventWindow(), *wg\Parent, EventType()) ; good uncomment to see
 
But i'm not sure what you want to do with the PostEvents. Do you want to notify the \Parent if the \Gadget receives a mouse move?
I wanted to inherit all events of the gadget for the parent.
Last edited by mestnyi on Mon Nov 20, 2017 5:54 pm, edited 1 time in total.
#NULL
Addict
Addict
Posts: 1440
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: Post event and canvas

Post by #NULL »

my PostEvent does not make sense, but neither does yours :) . instead of GadgetData 'Gadget' or '*wg\Parent' it should be just '*wg' so it can be assigned to '*wg.WindowStruct = ...' in the callback. but it is not used up to now anyway.

<edit>
Not sure what is 'pure', but i see now that your code does the same thing. it didn't look right to me at first, i apologize :)
#NULL
Addict
Addict
Posts: 1440
Joined: Thu Aug 30, 2007 11:54 pm
Location: right here

Re: Post event and canvas

Post by #NULL »

If you just pass the events to the other gadget, the receiving gadget will not know which gadget's mouse coordinates it should use. maybe the following helps:

Code: Select all

DeclareModule wg
  Declare Create(Gadget, X,Y,Width,Height, Title$="", Flag=0, Parent=-1)
EndDeclareModule

Module wg
  Structure WindowStruct
    Parent.i
    ParentMouseX.i
    ParentMouseY.i
    Gadget.i
    GadgetMouseX.i
    GadgetMouseY.i
  EndStructure
  
  Procedure draw(canvas, x, y)
    StartDrawing(CanvasOutput(canvas))
      Box(x, y, 2, 2, $999999)
    StopDrawing()
  EndProcedure
  
  Enumeration #PB_EventType_FirstCustomValue
    #CustomEventType_MouseMoveNotify
  EndEnumeration
  
  Procedure ParentCallBack()
    Static OffsetX, OffsetY
    Protected Gadget = EventGadget()
    Protected *wg.WindowStruct = GetGadgetData(Gadget)
    Select Event()
      Case #PB_Event_Gadget
        Select EventType()
          Case #PB_EventType_MouseMove
            *wg\ParentMouseX = GetGadgetAttribute(Gadget, #PB_Canvas_MouseX)
            *wg\ParentMouseY = GetGadgetAttribute(Gadget, #PB_Canvas_MouseY)
            draw(*wg\Parent, *wg\ParentMouseX, *wg\ParentMouseY)                                              ; draw with using \Parent coordinates
            PostEvent(#PB_Event_Gadget, EventWindow(), *wg\Gadget, #CustomEventType_MouseMoveNotify, *wg)     ; notify \Gadget with the stored coordinates
          Case #CustomEventType_MouseMoveNotify
            draw(*wg\Parent, *wg\GadgetMouseX, *wg\GadgetMouseY)                                              ; got notified. draw using \Gadget coordinates
        EndSelect
      Default
        Debug Event()
    EndSelect
  EndProcedure
 
  Procedure CallBack()
    Protected Gadget = EventGadget()
    Protected *wg.WindowStruct = GetGadgetData(Gadget)
    Select Event()
      Case #PB_Event_Gadget
        Select EventType()
          Case #PB_EventType_MouseMove
            *wg\GadgetMouseX = GetGadgetAttribute(Gadget, #PB_Canvas_MouseX)
            *wg\GadgetMouseY = GetGadgetAttribute(Gadget, #PB_Canvas_MouseY)
            draw(*wg\Gadget, *wg\GadgetMouseX, *wg\GadgetMouseY)                                              ; draw with using \Parent coordinates
            PostEvent(#PB_Event_Gadget, EventWindow(), *wg\Parent, #CustomEventType_MouseMoveNotify, *wg)     ; notify \Parent with the stored coordinates
          Case #CustomEventType_MouseMoveNotify
            draw(*wg\Gadget, *wg\ParentMouseX, *wg\ParentMouseY)                                              ; got notified. draw using \Parent coordinates
        EndSelect
      Default
        Debug Event()
    EndSelect
  EndProcedure
 
  Procedure Create(Gadget, X,Y,Width,Height, Title$="", Flag=0, Parent=-1)
    Protected *wg.WindowStruct = AllocateStructure(WindowStruct)
    
    With *wg
      \Parent = CanvasGadget(#PB_Any, x,y, Width,Height)
      
      \Gadget = CanvasGadget(Gadget, x+Width+10,y, Width,Height )
      If IsGadget(Gadget) : \Gadget = Gadget : EndIf
      
      SetGadgetData(\Parent, *wg)
      SetGadgetData(\Gadget, *wg)
      
      BindGadgetEvent(\Parent, @ParentCallBack())
      BindGadgetEvent(\Gadget, @CallBack(), #PB_EventType_MouseMove)
      BindGadgetEvent(\Gadget, @CallBack(), #CustomEventType_MouseMoveNotify)
     
      ProcedureReturn \Gadget
    EndWith
  EndProcedure
 
 
EndModule

;- Example
CompilerIf #PB_Compiler_IsMainFile
  Enumeration
    #Window
  EndEnumeration
 
  Procedure OpenWindow_0()
    OpenWindow(#Window, 0, 0, 600, 400, "WindowTitle",
               #PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
   
    wg::Create(2,30,30,100,100)
    ;wg::Create(#PB_Any,30,230,100,100)
   
  EndProcedure
 
  OpenWindow_0()
 
  Repeat
   
    Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
        End
    EndSelect
   
  ForEver
CompilerEndIf
Fred
Administrator
Administrator
Posts: 16619
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Post event and canvas

Post by Fred »

It doesn't work because the gadget expect a real canvas event (with specific EventData() attached to it). Just simulate a PostEvent() on canvas and trying to get the attribute won't work. PostEvent() is mainly created for user event.
Post Reply