with "# PB_Event_Gadget" and "EventGadget ()" should do some

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

Re: with "# PB_Event_Gadget" and "EventGadget ()" should do

Post by mestnyi »

Works very well, thank you.
MuseMove; LeftDown; LeftUp. If there would be pleased :D

Code: Select all

  CompilerIf Not Defined(PB_Object_Count, #PB_Function) And
             Not Defined(PB_Object_Count, #PB_Procedure) 
    CompilerIf #PB_Compiler_OS = #PB_OS_Windows
      Import ""
      CompilerElse
        ImportC ""
        CompilerEndIf
        PB_Object_EnumerateStart( PB_Objects )
        PB_Object_EnumerateNext( PB_Objects, *ID.Integer )
        PB_Object_EnumerateAbort( PB_Objects )
        
        PB_Object_Count( PB_Objects )
        
        PB_Window_Objects.i
        PB_Gadget_Objects.i
        PB_Image_Objects.i
      EndImport
  CompilerEndIf

  CompilerIf Not Defined(EnumerateStartGadget, #PB_Function) And
             Not Defined(EnumerateStartGadget, #PB_Procedure) 
    EnableExplicit
    
    ProcedureDLL CountWindow() ;Returns count window
      ProcedureReturn PB_Object_Count(PB_Window_Objects)
    EndProcedure
    
    ProcedureDLL CountGadget() ;Returns count gadget
      ProcedureReturn PB_Object_Count(PB_Gadget_Objects)
    EndProcedure
    
    ProcedureDLL CountImage() ;Returns count image
      ProcedureReturn PB_Object_Count(PB_Image_Objects)
    EndProcedure
    
    
    ProcedureDLL EnumerateStartWindow() ;Returns pb window object 
      PB_Object_EnumerateStart(PB_Window_Objects)
      ProcedureReturn PB_Window_Objects
    EndProcedure
    
    ProcedureDLL EnumerateStartGadget() ;Returns pb gadget object 
      PB_Object_EnumerateStart(PB_Gadget_Objects)
      ProcedureReturn PB_Gadget_Objects
    EndProcedure
    
    ProcedureDLL EnumerateStartImage() ;Returns pb Image object 
      PB_Object_EnumerateStart(PB_Image_Objects)
      ProcedureReturn PB_Image_Objects
    EndProcedure
    
    
    ProcedureDLL EnumerateNextWindow( *Window.Integer ) ;Returns next enumerate pb object 
      Protected PBObject, Window =-1
      PBObject = PB_Object_EnumerateNext( PB_Window_Objects, @Window )
      
      If IsWindow( Window )
        PokeI( *Window, PeekI( @Window ) )
      EndIf
      
      ProcedureReturn PBObject
    EndProcedure
    
    ProcedureDLL EnumerateNextGadget2( *Gadget.Integer, Window ) 
      Protected PBObject, WindowID, GadgetID, GadgetWindowID, Gadget =-1
      PBObject = PB_Object_EnumerateNext(PB_Gadget_Objects, @Gadget)
      
      If IsGadget( Gadget )
        PokeI( *Gadget, PeekI( @Gadget ) )
      EndIf
      
      If (IsWindow(Window) And IsGadget(Gadget))
        WindowID = WindowID( Window )
        GadgetID = GadgetID( Gadget )
        CompilerSelect #PB_Compiler_OS 
          CompilerCase #PB_OS_Linux 
            GadgetWindowID = gtk_widget_get_toplevel_ ( GadgetID )
          CompilerCase #PB_OS_Windows
            While GadgetID 
              GadgetWindowID = GadgetID
              GadgetID = GetParent_( GadgetID )
              If Not GadgetID
                Break
              EndIf
            Wend 
        CompilerEndSelect
        
        If GadgetWindowID = WindowID
          ProcedureReturn PBObject
        Else
          ProcedureReturn EnumerateNextGadget2( *Gadget, Window )
        EndIf  
      Else
        ProcedureReturn PBObject
      EndIf  
    EndProcedure
    ProcedureDLL EnumerateNextGadget( *Gadget ) ;Returns next enumerate pb object  
      ProcedureReturn EnumerateNextGadget2( *Gadget, #PB_All )
    EndProcedure
    Macro EnumerateNextGadget( Gadget, Window = #PB_All ) 
      EnumerateNextGadget2( Gadget, Window ) 
    EndMacro
    
    ProcedureDLL EnumerateNextImage( *Image.Integer ) ;Returns next enumerate pb object 
      Protected PBObject, Image =-1
      PBObject = PB_Object_EnumerateNext(PB_Image_Objects, @Image)
      
      If IsImage( Image )
        PokeI( *Image, PeekI( @Image ) )
      EndIf
      
      ProcedureReturn PBObject
    EndProcedure
    
    
    ProcedureDLL EnumerateAbortWindow() ;Abort enumerate window
      ProcedureReturn PB_Object_EnumerateAbort(PB_Window_Objects)
    EndProcedure
    
    ProcedureDLL EnumerateAbortGadget() ;Abort enumerate gadget
      ProcedureReturn PB_Object_EnumerateAbort(PB_Gadget_Objects)
    EndProcedure
    
    ProcedureDLL EnumerateAbortImage() ;Abort enumerate image
      ProcedureReturn PB_Object_EnumerateAbort(PB_Image_Objects)
    EndProcedure
    
    DisableExplicit
  CompilerEndIf
  
  ;: MouseEnter and MouseLeave
;: Example for all Gadgets crossplatform

DeclareModule xTraEvents
  
  Declare RegisterGadget(Window, Gadget)
  
EndDeclareModule
Module xTraEvents
  
  EnableExplicit
  
  Structure struct_xtra
    Thread.i
    Window.i
    List Gadget.i()
  EndStructure
  
  Global Mutex = CreateMutex()
  
  Procedure wThread(*p.struct_xtra)
    
    Protected OldGadget = -1
    Protected NewGadget = -1
    Protected mx, my
    
    If Not *p : ProcedureReturn #False : EndIf
    
    Repeat
      
      ;: Check Windows or free all
      If Not IsWindow(*p\Window)
        FreeList(*p\Gadget())
        FreeStructure(*p)
        ProcedureReturn #False
      EndIf
      ;: Get Mouse Position
      mx = WindowMouseX(*p\Window) : my = WindowMouseY(*p\Window)
      ;: Set Variables
      NewGadget = -1
      
      ;: Check if mouse is over a gadget
      ForEach *p\Gadget()
        
        If IsGadget(*p\Gadget()) ; Check Gadget
          If mx => GadgetX(*p\Gadget()) And mx <= (GadgetX(*p\Gadget()) + GadgetWidth(*p\Gadget()))
            If my => GadgetY(*p\Gadget()) And my <= (GadgetY(*p\Gadget()) + GadgetHeight(*p\Gadget()))  
              NewGadget = *p\Gadget()
              Break ; Leave loop if mouse is in a gadget that is registered
            EndIf
          EndIf        
        Else ; Or delete it
          LockMutex(Mutex)
          DeleteElement(*p\Gadget(), 1)
          UnlockMutex(Mutex)
        EndIf
        
      Next
      
      ;: Check wich gadget is entering and leaving and send a message to the window
      If NewGadget = -1
        If OldGadget <> NewGadget
          PostEvent(#PB_Event_Gadget, *p\Window, OldGadget, #PB_EventType_MouseLeave)
          OldGadget = NewGadget  
        EndIf
      Else
        If OldGadget <> NewGadget
          If IsGadget(OldGadget)
            PostEvent(#PB_Event_Gadget, *p\Window, OldGadget, #PB_EventType_MouseLeave)
          EndIf
          OldGadget = NewGadget
          PostEvent(#PB_Event_Gadget, *p\Window, NewGadget, #PB_EventType_MouseEnter)
        EndIf
      EndIf
      
      Delay(1) ; No barbecue
    ForEver
    
  EndProcedure
  
  Procedure RegisterGadget(Window, Gadget)
    
    Protected *p.struct_xtra
    
    If Not IsGadget(Gadget) : ProcedureReturn #False : EndIf
    
    If IsWindow(Window)
      *p = GetWindowData(Window)
      If Not *p
        *p = AllocateStructure(struct_xtra)
        SetWindowData(Window, *p)  
      EndIf
      If Not *p : ProcedureReturn #False : EndIf
      *p\Window = Window
      LockMutex(Mutex)
      AddElement(*p\Gadget())
      *p\Gadget() = Gadget
      UnlockMutex(Mutex)
      If Not *p\Thread
        *p\Thread = CreateThread(@wThread(), *p)
      EndIf
    Else
      ProcedureReturn #False
    EndIf
    
    ProcedureReturn #True
    
  EndProcedure  
  
EndModule

CompilerIf #PB_Compiler_IsMainFile
  UseModule xTraEvents
  
   X = 200
    For i = 1 To 4
      OpenWindow(i, 200, X, 150, 60, "Window_" + Trim(Str(i)))
      ContainerGadget(i*5, 5, 5, 120,50, #PB_Container_Flat)
      ButtonGadget(i,10,10,100,30,"Button_" + Trim(Str(i)))
      CloseGadgetList()
      X + 100
    Next
    
    If EnumerateStartWindow( )
      While EnumerateNextWindow( @Window )
        If EnumerateStartGadget( )
         While EnumerateNextGadget( @Gadget,Window )
         RegisterGadget(Window,Gadget)
        Wend
          EnumerateAbortGadget() 
        EndIf
      Wend
      EnumerateAbortWindow()
    EndIf
   
    Repeat
      If CountWindow( ) 
        Event = WaitWindowEvent( )
        If Event = #PB_Event_CloseWindow
          CloseWindow( EventWindow( ) )
          Debug "Close " + EventWindow( )
        ElseIf Event = #PB_Event_Gadget
          If EventType() = #PB_EventType_MouseEnter
            Debug "Enter " + EventGadget()
          ElseIf EventType() = #PB_EventType_MouseLeave
            Debug "Leave " + EventGadget()
          EndIf
        EndIf
      Else 
        Break
      EndIf
    ForEver
    
    Debug "Exit"
  CompilerEndIf
Didaktik
User
User
Posts: 79
Joined: Fri Mar 14, 2014 2:12 pm

Re: with "# PB_Event_Gadget" and "EventGadget ()" should do

Post by Didaktik »

Bisonte wrote:A simple method to add two events to any gadget crossplatform (thread)

Code: Select all

;: MouseEnter and MouseLeave
;: Example for all Gadgets crossplatform


Edit: Correcting typo[/quote]

Your code work wrong with ScrollArea.
User avatar
Bisonte
Addict
Addict
Posts: 1320
Joined: Tue Oct 09, 2007 2:15 am

Re: with "# PB_Event_Gadget" and "EventGadget ()" should do

Post by Bisonte »

Wich OS, and event you want to add ?

Maybe its not my solution...
PureBasic 6.21 (Windows x64) | Windows 11 Pro | AsRock B850 Steel Legend Wifi | R7 9800x3D | 64GB RAM | RTX 5080 | ThermaltakeView 270 TG ARGB | build by vannicom​​
English is not my native language... (I often use DeepL.)
Post Reply