NSPopOver Functions
Posted: Wed Nov 12, 2025 12:55 pm
This is a set of functions for NSPopOver functions:
Code: Select all
#NSMaxYEdge = 2 ; 0-3 change the orientation
Global popover = 0
Global vc = 0
Global contentView = 0
Global label = 0
; Create
Procedure.i CreateContentView(width, height)
Protected rect.NSRect
rect\origin\x = 0 : rect\origin\y = 0
rect\size\width = width : rect\size\height = height
Protected view = CocoaMessage(0, 0, "NSView alloc")
view = CocoaMessage(0, view, "initWithFrame:@", @rect)
ProcedureReturn view
EndProcedure
; Create a label
Procedure.i CreateLabel(parentView, x, y, w, h, text.s)
Protected labelRect.NSRect
labelRect\origin\x = x : labelRect\origin\y = y
labelRect\size\width = w : labelRect\size\height = h
Protected label = CocoaMessage(0, 0, "NSTextField alloc")
label = CocoaMessage(0, label, "initWithFrame:@", @labelRect)
CocoaMessage(0, label, "setStringValue:$", @text)
CocoaMessage(0, label, "setEditable:", #NO)
CocoaMessage(0, label, "setBordered:", #NO)
CocoaMessage(0, label, "setDrawsBackground:", #NO)
CocoaMessage(0, parentView, "addSubview:", label)
ProcedureReturn label
EndProcedure
; Create effect
Procedure.i CreatePopover(contentView, *out_vc.Integer)
Protected popover = CocoaMessage(0, 0, "NSPopover alloc")
popover = CocoaMessage(0, popover, "init")
Protected vc = CocoaMessage(0, 0, "NSViewController alloc")
vc = CocoaMessage(0, vc, "init")
CocoaMessage(0, vc, "setView:", contentView)
CocoaMessage(0, popover, "setContentViewController:", vc)
CocoaMessage(0, popover, "setAnimates:", #YES)
CocoaMessage(0, popover, "setBehavior:", 0)
If *out_vc
*out_vc\i = vc
EndIf
ProcedureReturn popover
EndProcedure
; Show relative to a PB gadget
Procedure ShowPopover(popover, gadget, preferredEdge = #NSMaxYEdge)
Protected gadgetID = GadgetID(gadget)
Protected btnRect.NSRect
CocoaMessage(@btnRect, gadgetID, "bounds")
CocoaMessage(0, popover, "showRelativeToRect:@", @btnRect, "ofView:", gadgetID, "preferredEdge:", preferredEdge)
EndProcedure
; Hide/close
Procedure HidePopover(popover, windowID = 0)
If popover
If windowID
CocoaMessage(0, popover, "performClose:", windowID)
Else
CocoaMessage(0, popover, "performClose:", 0)
EndIf
EndIf
EndProcedure
; Release popover
Procedure ReleasePopover(popover, vc, contentView = 0, label = 0)
If popover
CocoaMessage(0, popover, "close")
CocoaMessage(0, popover, "setContentViewController:", 0)
CocoaMessage(0, popover, "release")
EndIf
If vc
CocoaMessage(0, vc, "setView:", 0)
CocoaMessage(0, vc, "release")
EndIf
If contentView
If label
CocoaMessage(0, label, "removeFromSuperview")
CocoaMessage(0, label, "release")
EndIf
CocoaMessage(0, contentView, "release")
EndIf
EndProcedure
; Is it currently shown?
Procedure.i IsPopoverShown(popover)
ProcedureReturn CocoaMessage(0, popover, "isShown")
EndProcedure
If OpenWindow(0, 0, 0, 400, 200, "Demo", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
ButtonGadget(0, 150, 80, 100, 30, "Toggle Popover")
Repeat
Define ev = WaitWindowEvent()
If ev = #PB_Event_Gadget And EventGadget() = 0
If popover = 0
contentView = CreateContentView(200, 80)
label = CreateLabel(contentView, 20, 25, 160, 30, "Pop, Popover Muzik!")
popover = CreatePopover(contentView, @vc)
EndIf
If IsPopoverShown(popover)
HidePopover(popover, WindowID(0))
Else
ShowPopover(popover, 0)
EndIf
EndIf
Until ev = #PB_Event_CloseWindow
; Clean up
ReleasePopover(popover, vc, contentView, label)
EndIf