Seite 1 von 1

Mauseingabe mit PB_Event_Mouse* und #PB_EventType_*

Verfasst: 27.07.2008 11:19
von Danilo
Hi ^^ xD

Ich versuche gerade auf Linux ein sinnvolles Maushandling hinzubekommen,
aber mir sind ein paar Dinge aufgefallen:

Es gibt #PB_EventType_LeftClick und #PB_EventType_RightClick. Das ist schön.
Wäre es auch noch möglich dort #PB_EventType_LeftButtonDown/Up,
#PB_EventType_RightButtonDown/Up und #PB_EventType_MiddleButtonDown/Up hinzuzufügen?
LeftClick/RightClick feuern erst, wenn der jeweilige MouseButton wieder
losgelassen wurde, nicht sofort.

Vielleicht könnte man dann gleich noch #PB_EventType_MouseMove zu PB hinzufügen?
Das sollte dann direkt ein MouseMove auf einem Gadget sein, wobei man
die Möglichkeit haben sollte, abzufragen welche/ob MouseButtons während
des MouseMoves gedrückt sind.

Für das MouseMove habe ich die undokumentierte Konstante #PB_Event_MouseMove
gefunden.
Geht hier auf Linux, aber ich kann nichts überprüfen:
1. EventGadget() funktioniert damit nicht, um das Gadget herauszubekommen wo die Mouse drüberfährt.
2. Der Event kommt nur bei Gadgets, nicht beim Fenster selbst
3. Der Event kommt nur wenn auch gleichzeitig ein MouseButton gedrückt ist
4. Ich kann nicht herausfinden welcher MouseButton beim MouseMove gedrückt ist

Auch gibt es die geheimen Konstanten #PB_Event_MouseButtonDown
und #PB_Event_MouseButtonUp, aber die funktionieren hier nicht.


Meiner Meinung nach könnte man da noch etwas nachbessern, so daß
man MouseMessages auf allen OS für Gadgets+Windows platformunabhängig
besser verarbeiten kann.
Die Mouse-Library soll man dafür ja nicht nehmen:
PB-Hilfe hat geschrieben:Do not use the functions of this library in a regular application,
in this case carry out the mouse queries with WindowMouseX(), WindowMouseY() and EventType().
Hier mal mein Beispiel mit dem ich das auf Linux getestet habe:

Code: Alles auswählen

Procedure DrawGradient4(image,color1,color2,color3,color4)
  ;
  ; by Danilo
  ;
  ; draw gradient image with 4 colors,
  ; 4 colors = 4 corners.
  ;
  ;  color1/corner1           color2/corner2
  ;                |---------|
  ;                |         |
  ;                |         |
  ;                |         |
  ;                |         |
  ;                |---------|
  ;  color3/corner3           color4/corner4
  ;
  width  = ImageWidth(image)
  height = ImageHeight(image)
  ;
  r_diff1.f = (Red  (color1) - Red  (color3))/height
  g_diff1.f = (Green(Color1) - Green(Color3))/height
  b_diff1.f = (Blue (Color1) - Blue (Color3))/height
  ;
  r_diff2.f = (Red  (color2) - Red  (color4))/height
  g_diff2.f = (Green(Color2) - Green(Color4))/height
  b_diff2.f = (Blue (Color2) - Blue (Color4))/height
  ;
  If StartDrawing(ImageOutput(image))
    For y = 0 To height-1
      r_col_start.f = Red(color1)   - y*r_diff1
      r_col_end.f   = Red(color2)   - y*r_diff2
      g_col_start.f = Green(color1) - y*g_diff1
      g_col_end.f   = Green(color2) - y*g_diff2
      b_col_start.f = Blue(color1)  - y*b_diff1
      b_col_end.f   = Blue(color2)  - y*b_diff2
      ;
      r_diff3.f = (r_col_start - r_col_end)/width
      g_diff3.f = (g_col_start - g_col_end)/width
      b_diff3.f = (b_col_start - b_col_end)/width
      For x = 0 To width-1
        rcol.f = r_col_start - (x*r_diff3)
        gcol.f = g_col_start - (x*g_diff3)
        bcol.f = b_col_start - (x*b_diff3)
        Plot(x,y,RGB(rcol,gcol,bcol))
      Next x
    Next y
    StopDrawing()
  EndIf
EndProcedure


Procedure DrawCross(src,dest,x,y)
  If StartDrawing(ImageOutput(dest))
    DrawImage(ImageID(src),0,0)
    color=Point(x,y)
    Circle(x,y,4,0)
    ;Box(x-4,y-2,8,4,0)
    ;Box(x-2,y-4,4,8,0)
    ;Line(x-3,y,6,0,RGB($FF,$FF,$FF))
    StopDrawing()
  EndIf
  ProcedureReturn color
EndProcedure

Procedure CheckGadgetMouse(window,gadget,*x.Long,*y.LONG)
  If *x And *y
    retval = 1
    wx = WindowMouseX(window) : If wx = -1 : ProcedureReturn 0 : EndIf
    wy = WindowMouseY(window) : If wy = -1 : ProcedureReturn 0 : EndIf
    *x\l = wx-GadgetX(gadget)
    *y\l = wy-GadgetY(gadget)
    If *x\l < 0 : *x\l = 0 : retval = 0: EndIf
    If *y\l < 0 : *y\l = 0 : retval = 0: EndIf
    If *x\l > GadgetWidth(gadget) : *x\l = GadgetWidth(gadget)-1  : retval = 0 : EndIf
    If *y\l > GadgetHeight(gadget): *y\l = GadgetHeight(gadget)-1 : retval = 0 : EndIf
    ProcedureReturn retval
  EndIf
EndProcedure

Procedure UpdateRGBgadgets(color,r_gadget,g_gadget,b_gadget)
  SetGadgetText(r_gadget,"R: $"+RSet(Hex(Red  (color)),2,"0"))
  SetGadgetText(g_gadget,"G: $"+RSet(Hex(Green(color)),2,"0"))
  SetGadgetText(b_gadget,"B: $"+RSet(Hex(Blue (color)),2,"0"))
EndProcedure


If OpenWindow(0,0,0,400,500,"Colors",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
  If CreateGadgetList(WindowID(0))

    main_img1    = CreateImage(#PB_Any,390,390)
    main_img2    = CopyImage(main_img1,#PB_Any)
    DrawGradient4(main_img1,RGB($FF,$FF,$00),RGB($00,$FF,$FF),RGB($FF,$00,$00),RGB($00,$00,$FF))
    main_gadget = ImageGadget(#PB_Any,5,5,390,390,ImageID(main_img1))

    r_gadget = TextGadget(#PB_Any,5,400,100,20,"R:")
    g_gadget = TextGadget(#PB_Any,5,420,100,20,"G:")
    b_gadget = TextGadget(#PB_Any,5,440,100,20,"B:")

    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Break
        Case #PB_Event_Gadget
          If EventGadget()=main_gadget And EventType() = #PB_EventType_LeftClick
            Debug "Gadget LeftClick"
            If CheckGadgetMouse(0,main_gadget,@x,@y)
              color=DrawCross(main_img1,main_img2,x,y)
              SetGadgetState(main_gadget,ImageID(main_img2))
              UpdateRGBgadgets(color,r_gadget,g_gadget,b_gadget)
            EndIf
          ElseIf EventGadget()=main_gadget And EventType() = #PB_EventType_RightClick
            Debug "Gadget RightClick"
          EndIf
        Case #PB_Event_MouseButtonDown
          Debug "#PB_Event_MouseButtonDown"
        Case #PB_Event_MouseButtonUp
          Debug "#PB_Event_MouseButtonUp"
        Case #PB_Event_MouseMove
          Debug "#PB_Event_MouseMove"
        
          ;If EventGadget()=main_gadget ; funktioniert nicht
            If CheckGadgetMouse(0,main_gadget,@x,@y)
              color=DrawCross(main_img1,main_img2,x,y)
              SetGadgetState(main_gadget,ImageID(main_img2))
              UpdateRGBgadgets(color,r_gadget,g_gadget,b_gadget)
            EndIf
          ;EndIf
      EndSelect
    ForEver

  Else
    MessageRequester("Error","Can not create gadget list")
  EndIf
Else
  MessageRequester("Error","Can not open window")
EndIf

End
Oder ist das eher ein Feature Request?

Vielleicht weiß jemand mehr über die undokumentierten Nachrichten
und deren richtige Handhabung auf Linux (bzw. platformübergreifend)?

Vielen Dank an die liebe Gemeinde!

Verfasst: 27.07.2008 22:04
von mk-soft
WindowsMouseButton(...)

Code: Alles auswählen

Procedure WindowMouseButton(Wnd, ButtonNr)
 
  CompilerIf #PB_Compiler_OS = #PB_OS_Linux
  ;Linux Version
 
  Protected gdkWnd.l, x.l, y.l, mask.l
  Protected *Window.GTKWindow
  
  If Wnd
    *Window = Wnd
    gdkWnd = *Window\bin\child\window
    gdk_window_get_pointer_(gdkWnd, @x, @y, @mask)
   
    Select ButtonNr
      Case 0
        If (mask & #GDK_BUTTON1_MASK)
          ProcedureReturn #True
        EndIf
      Case 1
        If (mask & #GDK_BUTTON3_MASK)
          ProcedureReturn #True
        EndIf
      Case 2
        If (mask & #GDK_BUTTON2_MASK)
          ProcedureReturn #True
        EndIf
    EndSelect
  EndIf
 
  CompilerElse
  ;Windows Version
 
  If Wnd And GetForegroundWindow_() = Wnd
    Select ButtonNr
      Case 0
        If GetAsyncKeyState_(#VK_LBUTTON) > 0
          ProcedureReturn #True
        EndIf
      Case 1
        If GetAsyncKeyState_(#VK_RBUTTON) > 0
          ProcedureReturn #True
        EndIf
      Case 2
        If GetAsyncKeyState_(#VK_MBUTTON) > 0
          ProcedureReturn #True
        EndIf
    EndSelect
  EndIf
 
  CompilerEndIf
 
  ProcedureReturn #False
EndProcedure

Hatte ich irgendwo mal gefunden. Ich glaube im Codearchiv

Schon mal ein Teilansatz.

FF :wink:

P.S. Selber arbeite ich mit ein GadgetList (LinkedList) wo die Positionen der Gadgets und einige mehr abgelegt sind. Dann sucht das Programm die GadgetID über die Mouseposition in der LinkedList.

Verfasst: 28.07.2008 15:38
von Xaby
Ach ja, die Mouse-Events :D

Ich hab die Sache über InitMouse() gelöst.
Da kannste dir dann selbst mit den Eigenschaften der Maustasten Funktionen schreiben, die dir zurückgeben, ob die Maustaste gedrückt wurde, gedrückt ist oder nicht gedrückt wird.

Den QuellCode haste übrigens schon :D :allright:

Verfasst: 28.07.2008 16:37
von Danilo
mk-soft hat geschrieben:WindowsMouseButton(...)
[...]
Schon mal ein Teilansatz.
Danke, mk-soft. Ich bin trotzdem der Meinung, daß das Event-basiert
bei PB erweitert/nachgebessert werden könnte, so daß man es auf
allen Platformen gleich nutzen kann. Wenn man dafür immer 3 eigene
Versionen (Win,Linux,MacOS) mit versch. APIs/Toolkits schreiben muß,
ist der Zweck von PB IMO nicht erfüllt.

Die Verarbeitung von Mausereignissen bei Anwendungen über #PB_Event_*
und #PB_EventType_* könnte vielleicht nochmal überprüft werden.
Das soll nur eine Anregung meinerseits sein. Vielleicht möchte freak mal
sagen was er dazu meint.