Seite 2 von 3

Re: Zeichnen in Window

Verfasst: 12.11.2025 09:34
von MacThommes
um zurück zum Thema zu kommen: So sähe es mit einem ImageGadget aus:
Hab grad mal probiert....
Das funktioniert....
Heissa. Du bist mein Held!!
Ich liebe dieses Forum. So schnell, wie einem hier geholfen wird.
Das werde ich mir mal gleich ansehen um zu verstehen, wo da der Haken ist.
Also erst mal DANKE!!

Re: Zeichnen in Window

Verfasst: 12.11.2025 10:57
von Kiffi
wie Axolotl schon erwähnte:
Axolotl hat geschrieben: 11.11.2025 17:50Generell ist es besser ein Gadget zu verwenden, da die Rekonstruktion dann vom Gadget übernommen wird.
Geeignet wären hier ImageGadget oder CanvasGadget, abhängig davon wohin die Reise gehen soll.

Re: Zeichnen in Window

Verfasst: 12.11.2025 12:23
von Shardik
Axolotls modifiziertes Beispiel (mit #PB_Event_Repaint) läuft bis MacOS 10.13 'High Sierra' ebenfalls problemlos. Ab MacOS 10.14 'Mojave' hat Apple jedoch interne Änderungen vorgenommen, sodass ein direktes Zeichnen mit StartDrawing(WindowOutput()) seitdem nicht mehr funktioniert (und wovon ja sowieso abgeraten wird). Ab MacOS 'Mojave' hat ein NSWindow-Fenster immer automatisch den NSBackingStoreType NSBackingStoreNonretained, was bewirkt, dass Grafikoperationen direkt auf einem Fenster nicht mehr erscheinen. Das Fenster-Attribut NSBackingStoreNonretained kann leider nicht deaktiviert werden.

Mit API-Befehlen kann man aber auch in neueren MacOS-Versionen (erfolgreich getestet auf MacOS 15.7.1 'Sequoia') durch Einfügen eines Subview als Layer direkt in die Fensterfläche zeichnen. Hier ist ein Beispiel:

Code: Alles auswählen

EnableExplicit

Procedure DrawBox()
  Protected ContentView.I
  Protected Frame.NSRect
  Protected Layer.I
  Protected View.I

  Frame\origin\x = 100
  Frame\origin\y = 30
  Frame\size\width = 100
  Frame\size\height = 100
  View = CocoaMessage(0, CocoaMessage(0, 0, "NSView alloc"),
    "initWithFrame:@", @Frame)
  CocoaMessage(0, View, "setWantsLayer:", #YES)
  Layer = CocoaMessage(0, View, "layer")
  CocoaMessage(0, Layer,
    "setBackgroundColor:", CocoaMessage(0, CocoaMessage(0, 0,
    "NSColor redColor"), "CGColor"))
  ContentView = CocoaMessage(0, WindowID(0), "contentView")
  CocoaMessage(0, ContentView, "addSubview:", View)
EndProcedure

OpenWindow(0, 170, 100, 300, 200, "WindowOutput Example")
ButtonGadget(0, (WindowWidth(0) - 200) / 2, (WindowHeight(0) - 30) - 10, 200,
  30, "Draw red box into Window")

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 0
        DrawBox()
        DisableGadget(0, #True)
      EndIf
  EndSelect
ForEver

Re: Zeichnen in Window

Verfasst: 12.11.2025 13:53
von mk-soft
Mit einer älteren macOS Version ging es noch, dann wurde an der OS etwas geändert.
Es ist immer besser eine ImageGadget oder ein CanvasGadget zu nehmen. Dann muss man sich nicht selber um das neu Zeichnen zu kümmern.

Re: Zeichnen in Window

Verfasst: 13.11.2025 00:07
von MacThommes
Mit API-Befehlen kann man aber auch in neueren MacOS-Versionen (erfolgreich getestet auf MacOS 15.7.1 'Sequoia') durch Einfügen eines Subview als Layer direkt in die Fensterfläche zeichnen. Hier ist ein Beispiel:
Auch nicht schlecht. Funktioniert und bringt mich - so wie das andere Beispiel - schon mal viel weiter.
Danke an alle hier!
Ich denke, wir können das Thema schließen.
Aber keine Angst... Da kommen bestimmt noch einige Fragen von mir. :)

Re: Zeichnen in Window

Verfasst: 16.11.2025 19:34
von MacThommes
Hab da was seltsames gefunden:

Code: Alles auswählen

If OpenWindow(0, 800, 400, 800, 400, "Testfenster", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
  ButtonGadget(0, 340, 370, 100, 20, "OK", #PB_Button_Default)
  SetWindowColor(0,RGB(30,30,30))
  If CreateImage(1, 800, 400) And StartDrawing(ImageOutput(1))
    Box(0, 0, 800, 400, RGB(255, 0, 0))
    
    ImageGadget(0, 0, 0, 800, 400, ImageID(1))
  EndIf
  Repeat
    Event = WaitWindowEvent()
    Select Event
      Case #PB_Event_Gadget, #PB_Event_CloseWindow ; Gadget wurde angeklickt oder Fenster geschlossen
        out = 1
    EndSelect   
  Until out = 1  
  End
EndIf
Hier soll Fensterfüllend ein Viereck gezeichnet werden. Es wird aber nur die Hälfte gezeichnet.
Das Heisst: Dieses Viereck ist nur halb so hoch und halb so breit.
Aufgefallen ist mir das, als ich das Progrämmchen, was ich gerade schreibe, mal unter Linux compiliert habe. Da stimmt nichts mehr.
Eigentlich gehe ich davon aus, das die Werte, die bei den Befehleb wie Box, Circle usw. angegeben werden die Pixel sind.
Aber auf dem Mac ist das irgendwie nur die Hälfte.
Verdopple ich die Werte, funktioniert es....

Code: Alles auswählen

If OpenWindow(0, 800, 400, 800, 400, "Testfenster", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
  ButtonGadget(0, 340, 370, 100, 20, "OK", #PB_Button_Default)
  SetWindowColor(0,RGB(30,30,30))
  If CreateImage(1, 1600, 800) And StartDrawing(ImageOutput(1)) ; Doppelte Werte
    Box(0, 0, 1600, 800, RGB(255, 0, 0)) ; Doppelte Werte
    
    ImageGadget(0, 0, 0, 1600, 800, ImageID(1)); Doppelte Werte
  EndIf
  Repeat
    Event = WaitWindowEvent()
    Select Event
      Case #PB_Event_Gadget, #PB_Event_CloseWindow ; Gadget wurde angeklickt oder Fenster geschlossen
        out = 1
    EndSelect   
  Until out = 1  
  End
EndIf
Oder hab ich da einen Denkfehler?
Ich bin da jetzt sehr irritiert oder zu blöde?.

Re: Zeichnen in Window

Verfasst: 16.11.2025 19:44
von mk-soft
Es fehlt auf dem fall StopDrawing

Was hast du für einen Monitor und Welche Auflösung hast du. macOS Auflösung ist nicht unbedingt die Pixel Auflösung

Code: Alles auswählen

If OpenWindow(0, 800, 400, 800, 400, "Testfenster", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
  ButtonGadget(0, 340, 370, 100, 20, "OK", #PB_Button_Default)
  SetWindowColor(0,RGB(30,30,30))
  If CreateImage(1, 1600, 800)
    If StartDrawing(ImageOutput(1)) ; Doppelte Werte
      Box(0, 0, 1600, 800, RGB(255, 0, 0)) ; Doppelte Werte
      StopDrawing()
    EndIf
    ImageGadget(0, 0, 0, 1600, 800, ImageID(1)); Doppelte Werte
  EndIf
  Repeat
    Event = WaitWindowEvent()
    Select Event
      Case #PB_Event_Gadget, #PB_Event_CloseWindow ; Gadget wurde angeklickt oder Fenster geschlossen
        out = 1
    EndSelect   
  Until out = 1  
  End
EndIf

Re: Zeichnen in Window

Verfasst: 16.11.2025 19:52
von MacThommes
Hab die Auflösungen auf 2560 x 1440 stehen.
Beide Systeme laufen auf dem selben Rechner mit der selben Auflösung...
StopDrawing ist da. Vielleicht an der falschen Stelle, aber das Viereck wird gezeichnet.

Re: Zeichnen in Window

Verfasst: 16.11.2025 21:53
von MacThommes
Was ich nicht verstehe:
Wenn ich ein Fenster mit den Maßen 800 x 400 öffne und mir da ein Image von 800 x 400 erstelle (egal wie groß jetzt die Auflösung des Display ist, dann sollte dort auch ein Viereck von 800 x 400 die selbe Größe haben, oder?
Ich muß (!) die Werte bei CreateImage(), bei Box() und bei ImageGadget() verdoppeln - also 1600 x 800 - damit das Fenster ausgefüllt wird.
Unter Linux nicht....
Unter Windows 11 (Mit Parallels) ist es noch schlimmer. Da muß ich den Wert mehr wie verdreifachen, damit es passt.

Code: Alles auswählen

 
 out = 0
 ScreenBreite = DesktopWidth(0)
 ScreenHoehe = DesktopHeight(0)
 InfoBreite = 800
 InfoHoehe = 400
    
 If OpenWindow(1, (ScreenBreite/2)-400, (ScreenHoehe/2)-200, InfoBreite, InfoHoehe, "Test", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
      SetWindowColor(1,RGB(30,30,30))
      If CreateImage(1, InfoBreite, InfoHoehe) ; 800 Pixel breit und 400 Pixel hoch....
        Debug Str(InfoBreite)+ "   "+Str(InfoHoehe) ; Werden hier auch ausgegeben.
        StartDrawing(ImageOutput(1))
        Box(0,0,InfoBreite,InfoHoehe, RGB(255,0,0))  ; Soll eine Box von 800 x 400 in Rot zeichnen
        ImageGadget(1, 0, 0, 800, 400, ImageID(1)).    ; 800 x 400.... darstellen
        StopDrawing()
      EndIf
      ButtonGadget(5, 350, 370, 100, 20, "OK", #PB_Button_Default) ; noch einen Button drüberbügeln....
      Repeat
        Event = WaitWindowEvent()
        Select Event
          Case #PB_Event_Gadget, #PB_Event_CloseWindow ; Gadget wurde angeklickt oder Fenster geschlossen
            out = 1
        EndSelect   
      Until out = 1  
    CloseWindow(1)
    End
  EndIf

Re: Zeichnen in Window

Verfasst: 16.11.2025 22:26
von Bisonte
Das riecht gewaltig nach Skalierung ;)
Schau mal in den OS Einstellungen ob da eine Skalierung eingestellt ist...

Dann sind DesktopScaleX() usw. einen näheren Blick in die Hilfe Wert ...