Modul MouseOver

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
Shardik
Beiträge: 738
Registriert: 25.01.2005 12:19

Re: Modul MouseOver

Beitrag von Shardik »

Du hast in Dein Modul für Linux die Ermittlung von desktop_x und desktop_y eingebaut:

Code: Alles auswählen

          desktop_x = DesktopMouseX()
          desktop_y = DesktopMouseY()
          *GdkWindow.GdkWindowObject = gdk_window_at_pointer_(@desktop_x,@desktop_y)
Dies ist unnötig, weil gdk_window_at_pointer() die beiden Variablen desktop_x und desktop_y sowieso überschreibt, was ich in meinem Code-Beispiel auch berücksichtigt habe. Die GDK2-Dokumentation dazu ist eindeutig:
GDK2 Reference Manual hat geschrieben:gdk_window_at_pointer ()

GdkWindow *
gdk_window_at_pointer (gint *win_x, gint *win_y)

Obtains the window underneath the mouse pointer, returning the location of that window in win_x , win_y.
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Modul MouseOver

Beitrag von mk-soft »

@Shardik

Danke :wink:
Hab ich gleich korrigiert.

Werde noch ein Bugreport wegen der OSX (x86) Version schreiben.
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
mestnyi
Beiträge: 15
Registriert: 25.02.2014 22:00

Re: Modul MouseOver

Beitrag von mestnyi »

"FrameGadget" es wird nicht definiert,

Code: Alles auswählen

;- Example 1

CompilerIf #PB_Compiler_IsMainFile
  
  Enumeration FormWindow
    #Window_0
  EndEnumeration
  
  Enumeration FormGadget 
    #Frame_1 = 5
    #Button_1
  EndEnumeration
  
  
  Procedure OpenWindow_0(x = 0, y = 0, width = 610, height = 400)
    OpenWindow(#Window_0, x, y, width, height, "MouseOver Events", #PB_Window_SystemMenu)
    FrameGadget(#Frame_1, 50, 50, 140, 140, "FrameGadget") 
    ButtonGadget(#Button_1, 250, 50, 140, 140, "ButtonGadget")
  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
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Modul MouseOver

Beitrag von mk-soft »

Ist wohl von der OS abhängig ob das Objekt ein Handle liefert.
Bei Windows XP kommt nichts und bei Mac OS im Titel vom Frame.

In dem Zuge habe ich noch ein Bug beim "Init" mit der WindowsID gefunden. Ist wohl niemand aufgefallen.
Update im ersten Beitrag...
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
mestnyi
Beiträge: 15
Registriert: 25.02.2014 22:00

Re: Modul MouseOver

Beitrag von mestnyi »

Bug beim "Init"
PB_Gadget_Objects.i - dieses
PB_Window_Objects.i - stattdessen?
Ich habe gesehen. :D
und, was ist interessant, unter dem Cursor Frame Gadget sehen?
In Windows Textgadget erfordert flag '# SS_NOTIFI ", um das Click-Ereignis zu definieren
  Es muss eine Flagge, um Linux zu Frame Gadget unter dem Cursor festzustellen,
cptdark
Beiträge: 56
Registriert: 28.02.2010 14:13
Kontaktdaten:

Re: Modul MouseOver

Beitrag von cptdark »

Funktioniert mit PureBasic 5.42b1 unter GTK3 nicht mehr.
Da findet er wieder nur Gadget 1.

Mit GTK2 funktioniert es bestens.
Xubuntu 15.10 x64
Manjaro x64 * Windows 10 x64 * PureBasic 5.50
planet-RK
Omi
Beiträge: 143
Registriert: 25.03.2013 09:59

Re: Modul MouseOver

Beitrag von Omi »

Hallo cptdark.

Ab PB 5.40 ist in *GdkWindow.GdkWindowObject\user_data das GtkWindow nicht mehr bzw. falsch enthalten.
Versuche mal die Zeile

Code: Alles auswählen

handle = *GdkWindow\user_data
mit folgender Zeile zu ersetzen:

Code: Alles auswählen

gdk_window_get_user_data_(*GdkWindow, @handle)
Gruß Charly
PureBasic Linux-API-Library: http://www.chabba.de
cptdark
Beiträge: 56
Registriert: 28.02.2010 14:13
Kontaktdaten:

Re: Modul MouseOver

Beitrag von cptdark »

Dankeschön. Funktioniert so.
GTK2 und GTK3

:allright:
Manjaro x64 * Windows 10 x64 * PureBasic 5.50
planet-RK
Benutzeravatar
mk-soft
Beiträge: 3695
Registriert: 24.11.2004 13:12
Wohnort: Germany

Re: Modul MouseOver

Beitrag von mk-soft »

Update v1.05
- Bugfix Linux GTK3

Erledigt :wink:
Alles ist möglich, fragt sich nur wie...
Projekte ThreadToGUI / EventDesigner V3 / OOP-BaseClass-Modul
Downloads auf MyWebspace / OneDrive
Benutzeravatar
techniker
Beiträge: 160
Registriert: 27.01.2016 11:08
Wohnort: BY

Re: Modul MouseOver

Beitrag von techniker »

Eine kurze Frage:

Welche Funktion erfüllt die folgende Zeile in der Init-Routine..?

Code: Alles auswählen

If PB_Object_EnumerateNext(PB_Window_Objects, @window)
Da ich mehrere Fenster nutze und auch die Info erhalten möchte wo das Event aufgetreten ist,
habe ich den Code etwas umgeschrieben. Er läuft auch soweit. Jedoch habe ich diesen undokumentierten
Befehlen etwas Bauchweh.. /:->

Code: Alles auswählen

DeclareModule MouseOver
  Declare Init(window.l, timer=999)
  Declare Release(timer=999)
EndDeclareModule

;=============================================================================

Module MouseOver
  
  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
    Global lastgadget = -1
  
;=============================================================================
  
  Procedure EventHandler()
    
    Static lasthandle, 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, window_for_timer, 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, window_for_timer, gadget, #PB_EventType_MouseEnter)
            EndIf
            PB_Object_EnumerateAbort(PB_Gadget_Objects)
            Break
          EndIf
        Wend
        lasthandle = handle
      EndIf
    EndIf
    
  EndProcedure
  
  
  Procedure Init(window.l, timer=999)
    ;Protected window
    Release(timer)
    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
      lastgadget = -1
    EndIf
  EndProcedure
  
EndModule
Ich rufe nun in dem aktuellem Fenster jeweils die Init auf und kann somit über die Eventstruktur das Ereignis genau zuordnen.

=> Handle ich mir damit ggf. Probleme ein? :roll:
Never change a running system - Never run a changed system!
(PB 6.03 LTS [x86])
Antworten