Page 1 of 1

Post event and canvas

Posted: Mon Nov 20, 2017 6:35 am
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

Re: Post event and canvas

Posted: Mon Nov 20, 2017 3:35 pm
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.

Re: Post event and canvas

Posted: Mon Nov 20, 2017 4:25 pm
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.

Re: Post event and canvas

Posted: Mon Nov 20, 2017 5:11 pm
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

Re: Post event and canvas

Posted: Mon Nov 20, 2017 5:51 pm
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.

Re: Post event and canvas

Posted: Mon Nov 20, 2017 5:53 pm
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 :)

Re: Post event and canvas

Posted: Mon Nov 20, 2017 6:53 pm
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

Re: Post event and canvas

Posted: Sun Dec 02, 2018 10:31 am
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.