PureBoard
https://www.purebasic.fr/german/

Modul MouseOver
https://www.purebasic.fr/german/viewtopic.php?f=8&t=29047
Seite 1 von 3

Autor:  mk-soft [ 27.07.2015 14:50 ]
Betreff des Beitrags:  Modul MouseOver

Fügt die Gadgetevents MouseEnter und MouseLeave für alle Gadgets hinzu.

Update v1.01
- MacOS getestet

Update v1.02
- Windows x86 und x64
- Linux x86 und x64
- MacOS x64

Update v1.03
- Linux optimiert

Update v1.04
- Bugfix Init: falsche WindowsID für Timer

Update v1.05
- Bugfix Linux GTK3

Wegen ein Bug in PB v5.31 für MacOS (x86) beim Import ist es als Modul nicht lauffähig

Code:
;-Begin Module MouseOver
; Comment: Modul MouseOver
; Author : mk-soft
; Version: v1.05
; Created: 27.07.2015
; Updated: 03.02.2016
; Link   : http://www.purebasic.fr/german/viewtopic.php?f=8&t=29047   
;
; Thanks to:
;
; - Wilbert for mac functions get object under mouse
;     http://www.purebasic.fr/english/viewtopic.php?f=19&t=62056
;
; - Shardik for linux functions get object under mouse
;

DeclareModule MouseOver
  Declare Init(timer=999)
  Declare Release(timer=999)
EndDeclareModule

Module MouseOver
 
  ; Import internal function ------------------------------------------------------------
 
  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_GetObject( PB_Object , DynamicOrArrayID)
      PB_Window_Objects.i
      PB_Gadget_Objects.i
    EndImport
   
  ; -------------------------------------------------------------------------------------
 
  Global window_for_timer = -1
 
  ; -------------------------------------------------------------------------------------
 
  Procedure EventHandler()
   
    Static lasthandle, lastgadget = -1, x, y, last_x, last_y
   
    Protected gadget, handle
   
    x = WindowMouseX(EventWindow())
    y = WindowMouseY(EventWindow())
    If x <> last_x Or y <> last_y
      last_x = x
      last_y = y
     
      CompilerSelect #PB_Compiler_OS
        CompilerCase #PB_OS_Windows
          Protected desktop_x, desktop_y
          desktop_x = DesktopMouseX()
          desktop_y = DesktopMouseY()
          handle = WindowFromPoint_(desktop_y << 32 | desktop_x)
        CompilerCase #PB_OS_MacOS
          Protected win_id, win_cv, pt.NSPoint
          win_id = WindowID(EventWindow())
          win_cv = CocoaMessage(0, win_id, "contentView")
          CocoaMessage(@pt, win_id, "mouseLocationOutsideOfEventStream")
          handle = CocoaMessage(0, win_cv, "hitTest:@", @pt)
        CompilerCase #PB_OS_Linux
          Protected desktop_x, desktop_y, *GdkWindow.GdkWindowObject
          *GdkWindow.GdkWindowObject = gdk_window_at_pointer_(@desktop_x,@desktop_y)
          If *GdkWindow
            gdk_window_get_user_data_(*GdkWindow, @handle)
          Else
            handle = 0
          EndIf
      CompilerEndSelect
     
      If handle <> lasthandle
        If lastgadget >= 0
          If GadgetType(lastgadget) <> #PB_GadgetType_Canvas
            PostEvent(#PB_Event_Gadget, #PB_Ignore, lastgadget, #PB_EventType_MouseLeave)
          EndIf
          lastgadget = -1
        EndIf
        ; Find gadgetid over handle
        PB_Object_EnumerateStart(PB_Gadget_Objects)
        While PB_Object_EnumerateNext(PB_Gadget_Objects, @gadget)
          If handle = GadgetID(gadget)
            lastgadget = gadget
            If GadgetType(lastgadget) <> #PB_GadgetType_Canvas
              PostEvent(#PB_Event_Gadget, #PB_Any, gadget, #PB_EventType_MouseEnter)
            EndIf
            PB_Object_EnumerateAbort(PB_Gadget_Objects)
            Break
          EndIf
        Wend
        lasthandle = handle
      EndIf
    EndIf
   
  EndProcedure
 
  ; -------------------------------------------------------------------------------------
 
  Procedure Init(timer=999)
    Protected window
    PB_Object_EnumerateStart(PB_Window_Objects)
    If PB_Object_EnumerateNext(PB_Window_Objects, @window)
      AddWindowTimer(window, timer, 100)
      BindEvent(#PB_Event_Timer , @EventHandler())
      PB_Object_EnumerateAbort(PB_Window_Objects)
      window_for_timer = window
    EndIf
  EndProcedure
 
  ; -------------------------------------------------------------------------------------
 
  Procedure Release(timer=999)
    If window_for_timer >= 0
      UnbindEvent(#PB_Event_Timer , @EventHandler())
      RemoveWindowTimer(window_for_timer, timer)
      window_for_timer = -1
    EndIf
  EndProcedure
 
  ; -------------------------------------------------------------------------------------
 
EndModule

;-End Module MouseOver

; ***************************************************************************************

;- Example 1

CompilerIf #PB_Compiler_IsMainFile
 
  Enumeration FormWindow
    #Window_0
  EndEnumeration
 
  Enumeration FormGadget
    #Editor_0
    #Canvas_0
    #ExplorerList_0
    #ExplorerTree_0
    #ListView_0
    #ListIcon_0
    #Combo_0
    #Date_0
    #Option_0
    #Option_1
    #Checkbox_0
    #Hyperlink_0
    #IP_0
    #Button_0
    #Button_1
    #Button_2
    #Button_3
  EndEnumeration
 
 
  Procedure OpenWindow_0(x = 0, y = 0, width = 610, height = 400)
    OpenWindow(#Window_0, x, y, width, height, "MouseOver Events", #PB_Window_SystemMenu)
    EditorGadget(#Editor_0, 10, 10, 290, 60)
    CanvasGadget(#Canvas_0, 310, 10, 290, 60)
    ExplorerListGadget(#ExplorerList_0, 310, 80, 290, 100, "")
    ExplorerTreeGadget(#ExplorerTree_0, 10, 80, 290, 100, "")
    ListViewGadget(#ListView_0, 10, 190, 290, 60)
    ListIconGadget(#ListIcon_0, 310, 190, 290, 60, "Column 1", 100)
    ComboBoxGadget(#Combo_0, 10, 260, 290, 30)
    DateGadget(#Date_0, 310, 260, 290, 30, "")
    OptionGadget(#Option_0, 10, 300, 80, 30, "Option 1")
    OptionGadget(#Option_1, 100, 300, 90, 30, "Option 2")
    CheckBoxGadget(#Checkbox_0, 200, 300, 100, 30, "Check")
    HyperLinkGadget(#Hyperlink_0, 310, 300, 140, 30, "www.purebasic.com", 0)
    IPAddressGadget(#IP_0, 460, 300, 140, 30)
    ButtonGadget(#Button_0, 10, 340, 140, 40, "Button 0")
    ButtonGadget(#Button_1, 160, 340, 140, 40, "Button 1")
    ButtonGadget(#Button_2, 310, 340, 140, 40, "Button 2")
    ButtonGadget(#Button_3, 460, 340, 140, 40, "Button 3")
  EndProcedure

  OpenWindow_0()
 
  MouseOver::Init()
 
  Repeat
    Event = WaitWindowEvent(10)
    If Event = #PB_Event_Gadget
     
       Select EventType()
          Case #PB_EventType_MouseEnter
            Debug "MouseEnter Gadget " + EventGadget()
          Case #PB_EventType_MouseLeave
            Debug "MouseLeave Gadget " + EventGadget()
           
        EndSelect
    EndIf
   
  Until Event = #PB_Event_CloseWindow
 
CompilerEndIf

Autor:  Shardik [ 27.07.2015 23:35 ]
Betreff des Beitrags:  Re: Modul MouseOver

Schönes Modul und sehr nützlich, vielen Dank dafür!

Ich habe es unter MacOS X 10.6.8 (Snow Leopard) getestet:
- Mit PB 5.31 x64 (64 Bit) funktioniert es einwandfrei
- Mit PB 5.31 x86 (32 Bit) läuft es leider nicht und es werden folgende Fehler angezeigt:

Bild

Wenn man allerdings die Modulhülle entfernt, läuft es auch unter PB 5.31 x86 (32 Bit) einwandfrei!

Autor:  mestnyi [ 28.07.2015 02:25 ]
Betreff des Beitrags:  Re: Modul MouseOver

Code:
CompilerCase #PB_OS_Linux
          ; Code ?
          Protected desktop_x,desktop_y, *Widget.GtkWidget = gdk_window_at_pointer_(@desktop_x,@desktop_y)
          If (desktop_x <>-1 Or desktop_y <>-1)
            gdk_window_get_origin_(*Widget\object,@desktop_x,@desktop_y)
           
            handle = *Widget
          EndIf
       

Autor:  Shardik [ 28.07.2015 11:10 ]
Betreff des Beitrags:  Re: Modul MouseOver

Leider ist das Beispiel von mestnyi nicht korrekt. Wenn man es in das Modul einbaut, werden nur MouseEnter und MouseLeave für Gadget 1 angezeigt. Dies liegt daran, dass mestnyi die Rückgabestruktur für gdk_window_at_Pointer_() falsch definiert:
Code:
*Widget.GtkWidget = gdk_window_at_pointer_(@desktop_x,@desktop_y)
Diese Funktion gibt das GdkWindow des Gadgets zurück, das aktuell unter dem Mauszeiger liegt, sowie die x- und y-Koordinaten für die obere linke Ecke des Gadgets. Korrekt ist also:
Code:
*GdkWindow.GdkWindowObject = gdk_window_at_pointer_(@desktop_x,@desktop_y)

Außerdem ist seine Funktion
Code:
gdk_window_get_origin_(*Widget\object,@desktop_x,@desktop_y)
falsch und überflüssig, da sie für ein gegebenes GdkWindow eines Gadgets die x- und y-Werte in Root Window Koordinaten zurückgibt.

Dies ist das korrigierte Beispiel, das in das Modul eingefügt werden kann:
Code:
        CompilerCase #PB_OS_Linux
          Protected desktop_x,desktop_y,*GdkWindow.GdkWindowObject = gdk_window_at_pointer_(@desktop_x,@desktop_y)
          If *GdkWindow
            handle = *GdkWindow\user_data
          EndIf

Autor:  NicTheQuick [ 28.07.2015 11:49 ]
Betreff des Beitrags:  Re: Modul MouseOver

Cooles Snippet! :allright:
Ich wollte gestern schon die Linux-Version dazu posten, aber ich hab diese blöde 'gdk_window_at_pointer_'-Funktion nicht gefunden, warum auch immer.

Ich habe aber noch eine Frage. Die ganzen Funktionen wie 'PB_Object_EnumerateStart( PB_Objects )' und globale Werte wie 'PB_Gadget_Objects', sind die irgendwo dokumentiert. Ich kann zwar deren Namen aus allen PB-Libraries extrahieren, aber dann habe ich immer noch nicht die Parameter. ;)

Edit: Wäre übrigens auch hier ganz gut aufgehoben.

Autor:  edel [ 28.07.2015 13:13 ]
Betreff des Beitrags:  Re: Modul MouseOver

Informationen findest du im SDK Ordner (nur Windows). Erwarte davon aber nicht zuviel ;)

NicTheQuick hat geschrieben:
Ich kann zwar deren Namen aus allen PB-Libraries extrahieren, aber dann habe ich immer noch nicht die Parameter. ;)


Wie machst du das unter Linux, mit dumpdings?

Autor:  Shardik [ 28.07.2015 14:53 ]
Betreff des Beitrags:  Re: Modul MouseOver

Die letzte PureBasic-Version für Linux, die im Order /sdk/c/include die Header-Dateien für alle möglichen PB-Module (u.a. Gadget und Object) enthielt, war 4.20... :roll:

Autor:  mk-soft [ 28.07.2015 19:38 ]
Betreff des Beitrags:  Re: Modul MouseOver

Danke an allen für die Hilfe,

habe den Code jetzt für alle OS aktualisiert.

Läuft leider unter MacOS (x86) nicht als Modul. Denke aber das es sich um ein Bug in der 32bit Version für Mac liegt.

Alles Gute
Michael :allright:

P.S.
Zitat:
Die letzte PureBasic-Version für Linux, die im Order /sdk/c/include die Header-Dateien für alle möglichen PB-Module (u.a. Gadget und Object) enthielt, war 4.20


Fred hat angekündigt die SDK in der nächsten Release auch for Mac und Linux zu aktualisieren

http://www.purebasic.fr/english/viewtop ... 12&t=55344

Autor:  ts-soft [ 28.07.2015 19:48 ]
Betreff des Beitrags:  Re: Modul MouseOver

:allright:
Sehr brauchbar!

Autor:  Nino [ 28.07.2015 19:53 ]
Betreff des Beitrags:  Re: Modul MouseOver

Vielen Dank für das Modul!

Seite 1 von 3 Alle Zeiten sind UTC + 1 Stunde [ Sommerzeit ]
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
http://www.phpbb.com/