OpenWindowedScreen() und Mausbutton

In dieser Linux-Ecke dürfen nur Themen rund um Linux geschrieben werden.
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Benutzeravatar
blbltheworm
Beiträge: 217
Registriert: 22.09.2004 19:36
Wohnort: Auf der schönen Schwäbischen Alb

OpenWindowedScreen() und Mausbutton

Beitrag von blbltheworm »

Hallo zusammen,
ich habe hier im Moment ein Fenster mit Menü und einen WindowedScreen für das Zeichnen von Grafiken. Bei den Mausevents komme ich nun aber ziemlich durcheinander. D.h. ich weiß nicht, wie ich einen Mausklick abfrage. Im moment sieht der Code so ähnlich aus:

Code: Alles auswählen

InitSprite()
InitMouse()

OpenWindow(0,255,255,200,100,"test",#PB_Window_SystemMenu)
CreateMenu(0,WindowID(0))
MenuTitle("Test")
OpenWindowedScreen(WindowID(0),0,0,200,100-MenuHeight())
Repeat  
  Event = WindowEvent()
  EventType = EventType()
  
  ExamineMouse()
  Debug MouseButton(#PB_MouseButton_Left)
  ReleaseMouse(#True)
    
  Select Event
    Case #PB_Event_SizeWindow  

    Case #PB_Event_Menu
      EventMenu = EventMenu()
      ;Hier der Menüteil
  EndSelect
  ClearScreen(0)
  FlipBuffers()
          
Until Event = #PB_Event_CloseWindow
Ohne das ReleaseMouse() wird ja der Cursor nicht mehr angezeigt und somit ist auch das Menü nicht mehr bedienbar. Durch das ReleaseMouse() wird aber wohl auch MouseButton() zurückgesetzt. D.h. beim Maustaste drücken wird zwar einmal 1 ausgegeben, beim nächsten Durchlauf aber 0, auch wenn die Taste noch gedrückt ist.
Wie komme ich nun am Besten an die Info ob eine Maustaste gedrückt ist? Lässt sich das alternativ via GTK abfragen, damit ich die MouseLib nicht benötige oder wie bekomme ich das GTK-Fenster und den SDL-Screen in Harmonie? Über eine Abfrage von Event und EventType hatte ich bisher auch keine Chance :(

Ich bin für jeden Tipp dankbar.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6996
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: OpenWindowedScreen() und Mausbutton

Beitrag von STARGÅTE »

Die Mouse-Library mit ExamineMouse(), MouseButton() usw. verwaltet die Maus-Ereignisse alleine auf dem Screen, und dort musst/darfst/kannst du den Cursor auch selbst zeichnen (MouseX(), MouseY()).

Falls du mit dem Deskop-Cursor arbeiten willst, verwendest du nicht InitMouse(), ExamineMouse() usw.,
sondern wertest das WindowEvent aus. Dort bekommst du zB. einen #PB_Event_LeftClick.
Ob es unter Linux mehr Events gibt weiß ich aber nicht.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
blbltheworm
Beiträge: 217
Registriert: 22.09.2004 19:36
Wohnort: Auf der schönen Schwäbischen Alb

Re: OpenWindowedScreen() und Mausbutton

Beitrag von blbltheworm »

Hm,
genau das funktioniert bei mir unter Linux aber nicht.
Ohne das ReleaseMouse(#True) kann ich den Mauscursor auch außerhalb des Fensters nicht bewegen. Wenn ich InitMouse() & Co entferne, bekomme ich auch kein Event ausgeworfen, wenn ich auf den Screen klicke:

Code: Alles auswählen

InitSprite()

OpenWindow(0,255,255,200,100,"test",#PB_Window_SystemMenu)
CreateMenu(0,WindowID(0))
MenuTitle("Test")
OpenWindowedScreen(WindowID(0),0,0,200,100-MenuHeight())
Repeat 
  Event = WindowEvent()
  EventType = EventType()
 
  Select Event
    Case #PB_Event_LeftClick
      Debug "kommt nix"
    Case #PB_Event_SizeWindow 

    Case #PB_Event_Menu
      EventMenu = EventMenu()
    Default
      If event >0
        Debug Event
      EndIf
  EndSelect
  ClearScreen(0)
  FlipBuffers()
         
Until Event = #PB_Event_CloseWindow
Benutzeravatar
#NULL
Beiträge: 2235
Registriert: 20.04.2006 09:50

Re: OpenWindowedScreen() und Mausbutton

Beitrag von #NULL »

Du kannst beim Berühren der Screen-Ränder ReleaseMouse aufrufen und beim beim Wiedereintritt in den Screen die Maus dann wieder catchen.
Hier Beispiele aus dem englischen Forum:
Mouse lockt in window screen.
my pb stuff..
Bild..jedenfalls war das mal so.
Benutzeravatar
blbltheworm
Beiträge: 217
Registriert: 22.09.2004 19:36
Wohnort: Auf der schönen Schwäbischen Alb

Re: OpenWindowedScreen() und Mausbutton

Beitrag von blbltheworm »

Hi und danke für das Beispiel. Leider ist das Ganze so nicht praktikabel, wenn die Maus immer auf die Mitte des Screens zurückgesetzt wird. Weis zufällig wer, wie man mit GTK den Mauscursor plaziert (ich werde mich auch mal auf die Suche nach einem Codeschnippsel machen)?
Benutzeravatar
Shardik
Beiträge: 738
Registriert: 25.01.2005 12:19

Re: OpenWindowedScreen() und Mausbutton

Beitrag von Shardik »

Ich verstehe leider immer noch nicht genau, was Du machen möchtest. Möchtest Du nur, dass das Menü mit der Maus bedienbar bleibt? Ich habe einmal das 1.Beispiel aus der Hilfe für OpenWindowedScreen genommen, etwas vereinfacht und ein Menü hinzugefügt. Auf dem WindowedScreen bewegt sich ein gelber Sprite und das Menü funktioniert ebenfalls, da man das Programm mit Datei > Beenden beenden kann oder durch Betätigen der X-Schaltfläche oben rechts im Fensterrahmen. Was benötigst Du konkret noch zusätzlich?

Code: Alles auswählen

InitSprite()

OpenWindow(0, 200, 200, 200, 230, "Test")
CreateMenu(0, WindowID(0))
MenuTitle("Datei")
MenuItem(0, "Beenden")

If OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0), WindowHeight(0)) = 0
  MessageRequester("Fehler", "OpenWindowedScreen ist fehlgeschlagen!")
  End
Else
  CreateSprite(0, 20, 20)

  If StartDrawing(SpriteOutput(0))
    Box(0, 0, 20, 20, #Yellow)
    StopDrawing()
  EndIf
EndIf

Direction = 2

Repeat
  Select WindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Menu
      If EventMenu()=0
        Break
      EndIf
  EndSelect

  FlipBuffers() 
  ClearScreen(#Black)
  DisplaySprite(0, x, x)
  x + Direction

  If x > 180 : Direction = -2 : EndIf
  If x < 0   : Direction =  2 : EndIf
  Delay(10)
ForEver
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: OpenWindowedScreen() und Mausbutton

Beitrag von ccode_new »

Hallo!
So hier vielleicht ?

Code: Alles auswählen

UsePNGImageDecoder()

InitSprite() : InitMouse() : InitKeyboard()

CompilerIf #PB_Compiler_OS = #PB_OS_Linux
  ImportC ""
    gdk_display_get_default()
    gdk_display_get_pointer(*display.GdkDisplay, *screen.GdkScreen, *x, *y, *mask)
  EndImport
CompilerEndIf

Enumeration
  #MWin
  #CursorSprite
EndEnumeration

Structure WinPos
  x.i
  y.i
  h.i
  w.i
EndStructure

Global MWin.WinPos
MWin\x = 0
MWin\y = 0
MWin\w = 800
MWin\h = 600

Structure MPoint
  x.d
  y.d
EndStructure

Structure MText
  x.d
  y.d
  w.d
  h.d
  sel.i
  txt.s
EndStructure

Global Dim SelMenu.MText(2)

Global CMouse.MPoint

Procedure.b ScreenMouseButton(Wnd, ButtonNr)
  
  CompilerIf #PB_Compiler_OS = #PB_OS_Linux
    ;Linux Version
    If Wnd
      gdk_display_get_pointer(gdk_display_get_default(), #Null, @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_(#MK_LBUTTON) > 1
            ProcedureReturn #True
          EndIf
        Case 1
          If GetAsyncKeyState_(#MK_RBUTTON) > 1
            ProcedureReturn #True
          EndIf
        Case 2
          If GetAsyncKeyState_(#MK_MBUTTON) > 1
            ProcedureReturn #True
          EndIf
      EndSelect
    EndIf
  CompilerEndIf
  ProcedureReturn #False
EndProcedure

Procedure.b OverMenu(*MousePos.MPoint, *SelMenu.MText)
  If ((*MousePos\x >= *SelMenu\x) And (*MousePos\x <= (*SelMenu\x + *SelMenu\w)) And (*MousePos\y >= *SelMenu\y) And (*MousePos\y <= *SelMenu\y + *SelMenu\h))
    ProcedureReturn #True
  EndIf
  ProcedureReturn #False
EndProcedure

Procedure.b ScreenOpen()
  If OpenWindowedScreen(WindowID(#MWin),0,0,WindowWidth(#MWin),WindowHeight(#MWin),0,0,0)
    SetFrameRate(60)
    If Not CatchSprite(#CursorSprite, ?Cursor)
      End
    EndIf
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf
EndProcedure

Procedure ResizeScreen()
  MWin\w = WindowWidth(#MWin) : MWin\h = WindowHeight(#MWin)
  CloseScreen() ;???
  ScreenOpen()
EndProcedure

Procedure.b DrawMenu()
  SelMenu(0)\txt = "Auflösung 800 x 600 (4:3)"
  SelMenu(1)\txt = "Auflösung 1024 x 768 (4:3)"
  SelMenu(2)\txt = "Auflösung 1366 × 768 (16:9)"
  
  If StartDrawing(ScreenOutput())
    For i = 0 To 2
      SelMenu(i)\w = TextWidth(SelMenu(i)\txt)
      SelMenu(i)\h = TextHeight(SelMenu(i)\txt)
      SelMenu(i)\x = 0
      SelMenu(i)\y = 0 + 30*i
      SelMenu(i)\sel = i
      
      If(OverMenu(@CMouse, @SelMenu(i)))
        DrawText(SelMenu(i)\x, SelMenu(i)\y, SelMenu(i)\txt, RGB(255,255,0))
        If ScreenMouseButton(WindowID(#MWin), 0) And MouseButton(#PB_MouseButton_Left) ;Hier schauen!
          Debug "klick"
          If SelMenu(i)\sel = 0
            MWin\w = 800 : MWin\h = 600
          ElseIf SelMenu(i)\sel = 1
            MWin\w = 1024 : MWin\h = 768
          ElseIf SelMenu(i)\sel = 2
            MWin\w = 1366 : MWin\h = 768
          EndIf
          ResizeWindow(#MWin, #PB_Ignore, #PB_Ignore, MWin\w, MWin\h)
        EndIf
      Else
        DrawText(SelMenu(i)\x, SelMenu(i)\y, SelMenu(i)\txt, RGB(255,255,255))
      EndIf
    Next i
    StopDrawing()
    ProcedureReturn #True
  Else
    ProcedureReturn #False
  EndIf
EndProcedure

;Main
If OpenWindow(#MWin,MWin\x,MWin\y,MWin\w,MWin\h,"Maus-Menü",#PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget)   
  ;BindEvent( #PB_Event_SizeWindow, @ResizeScreen(), #MWin, #PB_All, #PB_All )
  CreateMenu(0,WindowID(#MWin))
  MenuTitle("Test")
  MenuItem(1,"Test")
  
  If ScreenOpen()
    Repeat
      CMouse\x = WindowMouseX(#MWin)
      CMouse\y = WindowMouseY(#MWin)
      
      ExamineKeyboard()
      
      ClearScreen(RGB(0,0,0))
      
      DrawMenu()
      
      ;DisplayTransparentSprite(#CursorSprite, CMouse\x, CMouse\y)
      
      FlipBuffers():Delay(10)
      
      Repeat
        EventID = WindowEvent()
        
        Select EventID
          Case #PB_Event_CloseWindow
            End
          Case #PB_Event_SizeWindow
            ResizeScreen()
          Case #PB_Event_Menu
            Debug "Menü"
        EndSelect
      Until EventID = 0
      
    Until KeyboardPushed(#PB_Key_Escape) Or EventID = #PB_Event_CloseWindow
  EndIf
EndIf

DataSection
  Cursor:
  Data.q $0A1A0A0D474E5089,$524448490D000000,$170000000F000000,$82315B0000000208,$4E527406000000EB
  Data.q $6E00000000000053,$70090000009107A6,$00C40E0000735948,$1B0E2B9501C40E00,$544144497D000000
  Data.q $20C00DCB919D8D38,$498758F20CD2C50C,$44A87A1160ED8A18,$086D921B94F90A51,$0E804A5280174510
  Data.q $BDA1E15E18C60008,$A082DB4AC25DA4C2,$0A3E96C26B4BE10D,$87AE10B4282F7A27,$36EB4A530389AD6E
  Data.q $58A7FD6D956B5CE7,$679E4A63382F69E9,$9E538D16D999BDF5,$88C39AAAEEF7A889,$7FBFE00F2C4EEB3C
  Data.q $8A09FED3D844A903,$4E454900000000F8,$000000826042AE44
EndDataSection
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Antworten