Re: [PB Cocoa] Methods, Tips & Tricks
Posted: Thu Jul 24, 2014 6:30 am
				
				Why would you want to resize external applications?
			http://www.purebasic.com
https://www.purebasic.fr/english/
I've explained that in my first message, please re-read:Danilo wrote:Why would you want to resize external applications?
The application being Lightwave 3D.grabiller wrote:../.. I'm trying to create a tool for an application that uses a lot of popup windows, to automatically arrange/snap/resize them in a clean way. The application is working on Windows & Mac but I only know how to do it on Windows. Would be great to have this tool working also on Mac OSX ../..
Here is the start to enum the windows and get the PID:grabiller wrote:I found this:
https://github.com/nint22/WindowSnaps/b ... Delegate.m
Code: Select all
ImportC ""
    CGWindowListCreate(_1, _2)
    CGWindowListCreateDescriptionFromArray(arr)
    CFArrayGetCount(arr)
    CFArrayGetValueAtIndex(arr, index)
    CFRelease(arr)
    CFDictionaryGetValue(_1,_2)
    CFStringCreateWithCharacters(alloc,text.p-Unicode,len)
    CFNumberGetValue(_1,_2,_3)
EndImport
;CFArrayRef
WindowList = CGWindowListCreate(1, 0)
Debug WindowList
DescriptionList = CGWindowListCreateDescriptionFromArray(WindowList)
Debug DescriptionList
Debug "--------------"
If DescriptionList
    count = CFArrayGetCount(DescriptionList)
    If count
        For i = 0 To count-1
            id = CFArrayGetValueAtIndex(DescriptionList,i)
            Debug "ID: "+id
            pid_num = CFDictionaryGetValue(id, CFStringCreateWithCharacters(0,"kCGWindowOwnerPID",17))
            If pid_num
                CFNumberGetValue(pid_num,9,@pid.l)
                Debug "PID: "+pid
            EndIf
        Next
    EndIf
EndIf
CFRelease(DescriptionList)
CFRelease(WindowList)Code: Select all
OpenWindow(0,0,0,0,0,"test",#PB_Window_SystemMenu|#PB_Window_Invisible)
mainScreen = CocoaMessage(0,0,"NSScreen mainScreen")
CocoaMessage(@visibleFrame.NSRect,mainScreen,"visibleFrame")
Debug visibleFrame\origin\x
Debug visibleFrame\origin\y
Debug visibleFrame\size\height
Debug visibleFrame\size\width
; origin\y starts from the bottom left corner of the screen, so to get the safe coordinates for PB we can calculate it like that:
ExamineDesktops()
winX = visibleFrame\origin\x
winY = DesktopHeight(0)-visibleFrame\size\height-visibleFrame\origin\y
titleBarH = WindowHeight(0,#PB_Window_FrameCoordinate)-WindowHeight(0,#PB_Window_InnerCoordinate)
winMaxW = visibleFrame\size\width
winMaxH = visibleFrame\size\height-titleBarH
Debug winX
Debug winY
Debug winMaxW
Debug winMaxH
ResizeWindow(0,winX,winY,winMaxW,winMaxH)
HideWindow(0,#False)
Repeat : ev = WaitWindowEvent() : Until ev = #PB_Event_CloseWindowCode: Select all
ImportC ""
  sel_registerName(STR.p-ascii)
  class_addMethod(class, selector, imp, types.p-ascii)
  objc_allocateClassPair(class, newClassName.p-ascii, extraBytes)
  objc_registerClassPair(class)
  object_setClass(object, class)
EndImport
Procedure SubClassGadget(Gadget, newClassName.s)
  Protected oldclass = CocoaMessage(0, GadgetID(Gadget), "class")
  Protected result = 0
  result = objc_allocateClassPair(oldclass, newClassName, 0)
  objc_registerClassPair(result)
  object_setClass(GadgetID(Gadget), result)
  ProcedureReturn result
EndProcedure
Procedure SubClassWindow(Window, newClassName.s)
  Protected oldclass = CocoaMessage(0, WindowID(Window), "class")
  Protected result = 0
  result = objc_allocateClassPair(oldclass, newClassName, 0)
  objc_registerClassPair(result)
  object_setClass(Window(Window), result)
  ProcedureReturn result
EndProcedure
Procedure CocoaAddMethod(Class, Method.s, CallBack)
  Protected sel = sel_registerName(Method)
  class_addMethod(Class, sel, CallBack, "v@:@")
EndProcedure
ProcedureC EventHandler(sender)
  Debug sender
  Debug "Escape Key Pressed"
EndProcedure
OpenWindow(0, 0, 0, 322, 205, "SubClassing", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
StringGadget(0, 8,  10, 306, 23, "StringGadget (Calls callback on ESC key)")
StringGadget(1, 8,  45, 306, 20, "Second String Gadget")
class = SubClassGadget(0, "MyStringGadget")
CocoaAddMethod(Class, "cancelOperation:", @EventHandler())    
Debug PeekS(CocoaMessage(0, CocoaMessage(0, GadgetID(0), "className"), "UTF8String"), -1, #PB_UTF8)
Repeat 
  event = WaitWindowEvent()
Until event  = #PB_Event_CloseWindow
Code: Select all
Procedure AppendItemToMenu(MenuItemID, Text$, Menu, MenuTitleIndex, ImageID=0)
  Protected mnuArray = MenuID(Menu)
  Protected newParent = CocoaMessage(0, mnuArray, "objectAtIndex:", MenuTitleIndex)
  Protected mItem = MenuItem(MenuItemID, Text$, ImageID)
  Protected oldParent = CocoaMessage(0, mItem, "menu")
  CocoaMessage(0, oldParent, "removeItem:", mItem)
  CocoaMessage(0, newParent, "addItem:", mItem)
  ProcedureReturn mItem
EndProcedure
Procedure AppendSubmenuToMenu(Text$, Menu, MenuTitleIndex, ImageID=0)
  Protected mnuArray = MenuID(Menu)
  Protected newParent = CocoaMessage(0, mnuArray, "objectAtIndex:", MenuTitleIndex)
  Protected mItem = MenuItem(0, Text$, ImageID)
  Protected subMenu = CocoaMessage(0, 0, "NSMenu alloc")
  CocoaMessage(0, subMenu, "initWithTitle:$", @Text$)
  Protected oldParent = CocoaMessage(0, mItem, "menu")
  CocoaMessage(0, oldParent, "removeItem:", mItem)
  CocoaMessage(0, newParent, "addItem:", mItem)
  CocoaMessage(0, mItem, "setSubmenu:", subMenu)
  ProcedureReturn subMenu
EndProcedure
Procedure AppendItemToSubmenu(MenuItemID, Text$, SubMenu, ImageID=0)
  Protected mItem = MenuItem(MenuItemID, Text$, ImageID)
  Protected oldParent = CocoaMessage(0, mItem, "menu")
  CocoaMessage(0, oldParent, "removeItem:", mItem)
  CocoaMessage(0, SubMenu, "addItem:", mItem)
  ProcedureReturn mItem
EndProcedure  
Procedure RemoveMenuItem(MenuItemHandle)
  Protected Parent = CocoaMessage(0, MenuItemHandle, "menu")
  CocoaMessage(0, Parent, "removeItem:", MenuItemHandle)
EndProcedure
; DEMO
OpenWindow(0, 200, 200, 200, 100, "Menu Example")
; create a menu and fill it with two MenuTitles and a few items
CreateMenu(0, WindowID(0)) 
; a file menu
MenuTitle("File")
MenuItem(1, "Open"   +Chr(9)+"Cmd+O")
MenuItem(2, "Save"   +Chr(9)+"Cmd+S")
; an edit menu
MenuTitle("Edit")
MenuItem(4, "Cut")
MenuItem(5, "Copy")
MenuItem(6, "Paste")
delme = MenuItem(7, "Delete me")
; now we append an item to the "File" menu (which is at index 0)
AppendItemToMenu(3, "Save as...", 0, 0)
; and we'll append a submenu to the first (index 0) menu too
sub = AppendSubmenuToMenu("Recent Files", 0, 0)
; our newly created sub menu needs a few items
AppendItemToSubmenu(100, "File number one"  +Chr(9)+"Shift+Cmd+1", sub, 0)
AppendItemToSubmenu(101, "File number two"  +Chr(9)+"Shift+Cmd+2", sub, 0)
AppendItemToSubmenu(102, "File number three"  +Chr(9)+"Shift+Cmd+3", sub, 0)
; get rid of the "delete me" item
RemoveMenuItem(delme)
Code: Select all
EnableExplicit
#Text = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam " +
  "nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, " +
  "sed diam voluptua. At vero eos et accusam et justo duo dolores et ea " +
  "rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum " +
  "dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, " +
  "sed diam nonumy eirmod tempor invidunt ut labor."
Procedure.I GetLineHeight(EditorGadgetID.I)
  Protected Dictionary.I
  Protected Font.I
  Protected i.I
  Protected KeyArray.I
  Protected KeyName.I
  Protected LineHeight.CGFloat
  Dictionary = CocoaMessage(0, GadgetID(EditorGadgetID), "typingAttributes")
  KeyArray = CocoaMessage(0, Dictionary, "allKeys")
  For i = 0 To CocoaMessage(0, KeyArray, "count") - 1
    KeyName = CocoaMessage(0, KeyArray, "objectAtIndex:", i)
    If PeekS(CocoaMessage(0, KeyName, "UTF8String"), -1, #PB_UTF8) = "NSFont"
      Font = CocoaMessage(0, Dictionary, "objectForKey:", KeyName)
      If Font
        CocoaMessage(@LineHeight, CocoaMessage(0, GadgetID(EditorGadgetID),
          "layoutManager"), "defaultLineHeightForFont:", Font)
      EndIf
      Break
    EndIf
  Next i
  ProcedureReturn Int(LineHeight)
EndProcedure
Procedure.I GetLineCount(EditorGadgetID.I)
  Protected LineHeight.I
  Protected Rect.NSRect
  Protected TextBlockHeight.I
  ; ----- Get height of text block
  CocoaMessage(@Rect, CocoaMessage(0, GadgetID(EditorGadgetID), "layoutManager"),
    "usedRectForTextContainer:", CocoaMessage(0, GadgetID(EditorGadgetID),
    "textContainer"))
  TextBlockHeight = Int(Rect\size\height)
  LineHeight = GetLineHeight(EditorGadgetID)
  ProcedureReturn TextBlockHeight / LineHeight
EndProcedure
OpenWindow(0, 200, 100, 300, 210, "EditorGadget")
EditorGadget(0, 5, 5, WindowWidth(0) - 10, WindowHeight(0) - 10,
  #PB_Editor_WordWrap)
SetGadgetFont(0, LoadFont(0, "Arial", 15))
SetGadgetText(0, #Text)
; ----- Wait until Text is displayed
While WindowEvent() : Wend
MessageRequester("Info", "Lines in EditorGadget: " + GetLineCount(0))
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindowCode: Select all
Procedure.i AudioPlayer(FileName.s)
  ProcedureReturn CocoaMessage(0, CocoaMessage(0, 0, "AVAudioPlayer alloc"), 
                               "initWithContentsOfURL:", CocoaMessage(0, 0, "NSURL fileURLWithPath:$", @FileName), 
                               "error:", #Null)
EndProcedure
Procedure SetVolumeAndPan(AudioPlayer.i, Volume.f = 1.0, Pan.f = 0.0)
  CocoaMessage(0, AudioPlayer, "setVolume:@", @Volume)
  CocoaMessage(0, AudioPlayer, "setPan:@", @Pan)
EndProcedure
Define.f LeftAverage, RightAverage, LeftPeak, RightPeak
OpenWindow(0, 0, 0, 270, 70, "AVAudioPlayer example (OSX 10.7+)", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(0, 0, 0, 270, 70)
If StartDrawing(CanvasOutput(0))
  Box(0, 0, 270, 70, $ff000000)
  DrawingMode(#PB_2DDrawing_Outlined)
  Box(10, 10, 250, 20, $ffe0e0e0)
  Box(10, 40, 250, 20, $ffe0e0e0)
  StopDrawing()
EndIf
AudioPlayer = AudioPlayer(OpenFileRequester("Choose a sound file", "", "", 0))
If AudioPlayer
  SetVolumeAndPan(AudioPlayer, 1.0, 0.0)
  CocoaMessage(0, AudioPlayer, "play")
  CocoaMessage(0, AudioPlayer, "setMeteringEnabled:", #YES)
  Repeat
    
    CocoaMessage(0, AudioPlayer, "updateMeters")
    CocoaMessage(@LeftAverage, AudioPlayer, "averagePowerForChannel:", 0)
    CocoaMessage(@RightAverage, AudioPlayer, "averagePowerForChannel:", 1)
    CocoaMessage(@LeftPeak, AudioPlayer, "peakPowerForChannel:", 0)
    CocoaMessage(@RightPeak, AudioPlayer, "peakPowerForChannel:", 1)
    If StartDrawing(CanvasOutput(0))
      DrawingMode(#PB_2DDrawing_AlphaBlend)
      Box(11, 11, 248, 18, $40000000)
      Box(11, 41, 248, 18, $40000000)
      Box(11, 11, 248 * Pow(10, 0.05 * LeftAverage), 18, $fffffc000)
      Box(11, 41, 248 * Pow(10, 0.05 * RightAverage), 18, $ffffc000)
      Box(11 + 246 * Pow(10, 0.05 * LeftPeak), 11, 2, 18, $fffffc000)
      Box(11 + 246 * Pow(10, 0.05 * RightPeak), 41, 2, 18, $ffffc000)      
      StopDrawing()
    EndIf
    
    Event = WaitWindowEvent(40)
  Until Event = #PB_Event_CloseWindow
EndIfCode: Select all
Enumeration CGWindowLevelKey
   #kCGBaseWindowLevelKey = 0
   #kCGMinimumWindowLevelKey
   #kCGDesktopWindowLevelKey
   #kCGBackstopMenuLevelKey
   #kCGNormalWindowLevelKey
   #kCGFloatingWindowLevelKey
   #kCGTornOffMenuWindowLevelKey
   #kCGDockWindowLevelKey
   #kCGMainMenuWindowLevelKey
   #kCGStatusWindowLevelKey
   #kCGModalPanelWindowLevelKey
   #kCGPopUpMenuWindowLevelKey
   #kCGDraggingWindowLevelKey
   #kCGScreenSaverWindowLevelKey
   #kCGMaximumWindowLevelKey
   #kCGOverlayWindowLevelKey
   #kCGHelpWindowLevelKey
   #kCGUtilityWindowLevelKey
   #kCGDesktopIconWindowLevelKey
   #kCGCursorWindowLevelKey
   #kCGAssistiveTechHighWindowLevelKey
   #kCGNumberOfWindowLevelKeys
EndEnumeration
#NSFloatingWindowLevel          = #kCGFloatingWindowLevelKey
#NSBorderlessWindowMask         = 0
#NSTitledWindowMask             = 1 << 0
#NSClosableWindowMask           = 1 << 1
#NSMiniaturizableWindowMask     = 1 << 2
#NSResizableWindowMask          = 1 << 3
#NSUtilityWindowMask            = 1 << 4
#NSDocModalWindowMask           = 1 << 6
#NSNonactivatingPanelMask       = 1 << 7
#NSTexturedBackgroundWindowMask = 1 << 8
#NSHUDWindowMask                = 1 << 13
w1=OpenWindow(#PB_Any, 80, 280, 100, 300, "")
HideWindow(w1,#True)
;Window_0 = OpenWindow(#PB_Any, 100, 300, 150, 300, "Utility");,WindowID(w1))
;NSPanel = WindowID(w1)
Procedure App()
    Protected app
    CocoaMessage(@app,0,"NSApplication sharedApplication")
    ProcedureReturn app
EndProcedure
Procedure InitRect(*rect.NSRect,x,y,width,height)
    If *rect
        *rect\origin\x = x
        *rect\origin\y = y
        *rect\size\width = width
        *rect\size\height = height
    EndIf
EndProcedure
Procedure Panel(x,y,width,height,title.s,mask,center=#True)
    Protected size.NSSize, rect.NSRect, win, view
    CocoaMessage(@win,0,"NSPanel alloc")
    If win
        InitRect(@rect,x,y,width,height)
        CocoaMessage(0,win,"initWithContentRect:@",@rect,"styleMask:",mask,"backing:",2,"defer:",#NO)
        ;CocoaMessage(0,win,"makeKeyWindow")
        CocoaMessage(0,Win,"makeKeyAndOrderFront:",App())
        CocoaMessage(0,win,"setTitle:$",@title)
        ;InitSize(@size,width,height)
        ;CocoaMessage(0,win,"setMinSize:",size)
        
        CocoaMessage(0,win,"setPreventsApplicationTerminationWhenModal:",#NO)
        CocoaMessage(0,win,"setReleasedWhenClosed:",#YES)
        
        
        CocoaMessage(@view,0,"NSView alloc")
        If view
            InitRect(@rect,0,0,width,height)
            CocoaMessage(@view,view,"initWithFrame:@",@rect)
            CocoaMessage(0,win,"setContentView:",view)
        EndIf
        
        If center
            CocoaMessage(0,win,"center")
        EndIf
        CocoaMessage(0,win,"update")
        CocoaMessage(0,win,"display")
     
    EndIf
    ProcedureReturn win
EndProcedure
Procedure OnBtnClick()
    End
EndProcedure
NSPanel = Panel(100,300,500,300,"HUD Window", #NSUtilityWindowMask|
                                              #NSTitledWindowMask|
                                              #NSClosableWindowMask|
                                              #NSMiniaturizableWindowMask|
                                              ;#NSTexturedBackgroundWindowMask|
                                              ;#NSNonactivatingPanelMask|
                                              #NSResizableWindowMask|
                                              #NSHUDWindowMask)
                                          
;CocoaMessage(0, NSPanel, "setStyleMask:", #NSUtilityWindowMask|
;                                          #NSTitledWindowMask|
;                                          #NSClosableWindowMask|
;                                          #NSMiniaturizableWindowMask|
;                                          ;#NSTexturedBackgroundWindowMask|
;                                          #NSResizableWindowMask) 
;CocoaMessage(0, NSPanel, "setFloatingPanel:",#YES)
;CocoaMessage(0, NSPanel, "setShowsResizeIndicator:",#YES)
CocoaMessage(0, NSPanel, "setMovableByWindowBackground:",#YES)
CocoaMessage(0, NSPanel, "setLevel:",#NSFloatingWindowLevel) ; stay on top
UseGadgetList( NSPanel )
ButtonGadget(0,340,5,150,25,"Exit")
;Filter  = CocoaMessage(0, 0, "CIFilter filterWithName:$", @"CIColorMonochrome") ; create a CIColorMonochrome filter
;CocoaMessage(0, Filter, "setDefaults")                                          ; set the default values for the filter
;Color = CocoaMessage(0, 0, "CIColor colorWithString:$", @"0.1 0.1 0.1 1.0")     ; create a CIColor object from a RGBA string
;CocoaMessage(0, Filter, "setValue:", Color, "forKey:$", @"inputColor")          ; assign the color to the filter
;FilterArray = CocoaMessage(0, 0, "NSArray arrayWithObject:", Filter)            ; create an array with only the filter
 
;Button = GadgetID(0)
;CocoaMessage(0, Button, "setWantsLayer:", #YES)                                 ; the gadget needs a layer for the filter to work
;CocoaMessage(0, Button, "setContentFilters:", FilterArray)                      ; set the filter Array
;// Field 1
TextGadget(2,10,250,250,20,"Field 1:"): SetGadgetColor(2, #PB_Gadget_FrontColor, $FFFFFF)
StringGadget(3,65,252,100,20,""): SetGadgetColor(3, #PB_Gadget_FrontColor, $FFFFFF): SetGadgetColor(3, #PB_Gadget_BackColor, $555555)
;// Field 2
TextGadget(4,10,220,250,20,"Field 2:"): SetGadgetColor(4, #PB_Gadget_FrontColor, $FFFFFF)
StringGadget(5,65,222,100,20,""): SetGadgetColor(5, #PB_Gadget_FrontColor, $FFFFFF): SetGadgetColor(5, #PB_Gadget_BackColor, $555555)
;// Option Gadgets
OptionGadget(6,10,190,100,20,"Option 1"): SetGadgetColor(6, #PB_Gadget_FrontColor, $FFFFFF): SetGadgetColor(6, #PB_Gadget_BackColor, $555555)
OptionGadget(7,120,190,100,20,"Option 2"): SetGadgetColor(7, #PB_Gadget_FrontColor, $FFFFFF): SetGadgetColor(7, #PB_Gadget_BackColor, $555555)
;// Circular Slider
TrackBarGadget(8,250,240,36,36,0,12)
Cell = CocoaMessage(0, GadgetID(8), "cell"): SetGadgetColor(8, #PB_Gadget_FrontColor, $FFFFFF): SetGadgetColor(8, #PB_Gadget_BackColor, $555555)
CocoaMessage(8, Cell, "setSliderType:", 1); circular slider
CocoaMessage(8, Cell, "setNumberOfTickMarks:", 12)
CocoaMessage(8, Cell, "setAllowsTickMarkValuesOnly:", #YES)
;// ListViewGadget
ListViewGadget(9,10,60,200,120): SetGadgetColor(9, #PB_Gadget_FrontColor, $FFFFFF): SetGadgetColor(9, #PB_Gadget_BackColor, $555555)
For a=1 To 12
  AddGadgetItem(9,-1,"Item " + Str(a) +" of the ListView")
Next
SetGadgetState(9,4)
;// Horizontal Scrollbar
ScrollBarGadget(10,230,42,150,20,0,100,30)
SetGadgetState(10,50)
;// Vertical Scrollbar
ScrollBarGadget(11,380,42,20,150,0,100,30)
SetGadgetState(11,100)
BindGadgetEvent(0,@OnBtnClick())
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
You have to remember that in the beginning of your code example you have opened window w1 and hidden it. When closing the HUD panel you have to also close that hidden window because otherwise your app will not terminate. The End statement in procedure OnBtnClick() is not sufficient. So I would propose to utilize PostEvent(#PB_Event_CloseWindow) to send the close event to your main event loop in order to properly terminate your program when clicking onto the Exit button:gwhuntoon wrote:I'm also not sure how to trap/respond to the #NSClosableWindowMask i.e. Close Gadget of the HUD Window (which isn't an actual window but an NSPanel object)
Code: Select all
Procedure OnBtnClick()
  PostEvent(#PB_Event_CloseWindow)
EndProcedureCode: Select all
ImportC ""
  class_addMethod(Class.I, Selector.I, *Callback, Types.P-ASCII)
  sel_registerName(MethodName.P-ASCII)
EndImport
ProcedureC PanelShouldCloseCallback(Object.I, Selector.I, Sender.I)
  PostEvent(#PB_Event_CloseWindow)
EndProcedure
class_addMethod(CocoaMessage(0, NSPanel, "class"),
  sel_registerName("windowShouldClose:"), @PanelShouldCloseCallback(), "v@:@")
CocoaMessage(0, WindowID(w1), "setDelegate:", AppDelegate)Code: Select all
Enumeration CGWindowLevelKey
   #kCGBaseWindowLevelKey = 0
   #kCGMinimumWindowLevelKey
   #kCGDesktopWindowLevelKey
   #kCGBackstopMenuLevelKey
   #kCGNormalWindowLevelKey
   #kCGFloatingWindowLevelKey
   #kCGTornOffMenuWindowLevelKey
   #kCGDockWindowLevelKey
   #kCGMainMenuWindowLevelKey
   #kCGStatusWindowLevelKey
   #kCGModalPanelWindowLevelKey
   #kCGPopUpMenuWindowLevelKey
   #kCGDraggingWindowLevelKey
   #kCGScreenSaverWindowLevelKey
   #kCGMaximumWindowLevelKey
   #kCGOverlayWindowLevelKey
   #kCGHelpWindowLevelKey
   #kCGUtilityWindowLevelKey
   #kCGDesktopIconWindowLevelKey
   #kCGCursorWindowLevelKey
   #kCGAssistiveTechHighWindowLevelKey
   #kCGNumberOfWindowLevelKeys
EndEnumeration
#NSFloatingWindowLevel          = #kCGFloatingWindowLevelKey
#NSBorderlessWindowMask         = 0
#NSTitledWindowMask             = 1 << 0
#NSClosableWindowMask           = 1 << 1
#NSMiniaturizableWindowMask     = 1 << 2
#NSResizableWindowMask          = 1 << 3
#NSUtilityWindowMask            = 1 << 4
#NSDocModalWindowMask           = 1 << 6
#NSNonactivatingPanelMask       = 1 << 7
#NSTexturedBackgroundWindowMask = 1 << 8
#NSHUDWindowMask                = 1 << 13
ImportC ""
  class_addMethod(Class.I, Selector.I, *Callback, Types.P-ASCII)
  sel_registerName(MethodName.P-ASCII)
EndImport
w1=OpenWindow(#PB_Any, 80, 280, 100, 300, "")
HideWindow(w1,#True)
;Window_0 = OpenWindow(#PB_Any, 100, 300, 150, 300, "Utility");,WindowID(w1))
;NSPanel = WindowID(w1)
Procedure App()
    Protected app
    CocoaMessage(@app,0,"NSApplication sharedApplication")
    ProcedureReturn app
EndProcedure
Procedure InitRect(*rect.NSRect,x,y,width,height)
    If *rect
        *rect\origin\x = x
        *rect\origin\y = y
        *rect\size\width = width
        *rect\size\height = height
    EndIf
EndProcedure
Procedure Panel(x,y,width,height,title.s,mask,center=#True)
    Protected size.NSSize, rect.NSRect, win, view
    CocoaMessage(@win,0,"NSPanel alloc")
    If win
        InitRect(@rect,x,y,width,height)
        CocoaMessage(0,win,"initWithContentRect:@",@rect,"styleMask:",mask,"backing:",2,"defer:",#NO)
        ;CocoaMessage(0,win,"makeKeyWindow")
        CocoaMessage(0,Win,"makeKeyAndOrderFront:",App())
        CocoaMessage(0,win,"setTitle:$",@title)
        ;InitSize(@size,width,height)
        ;CocoaMessage(0,win,"setMinSize:",size)
       
        CocoaMessage(0,win,"setPreventsApplicationTerminationWhenModal:",#NO)
        CocoaMessage(0,win,"setReleasedWhenClosed:",#YES)
       
       
        CocoaMessage(@view,0,"NSView alloc")
        If view
            InitRect(@rect,0,0,width,height)
            CocoaMessage(@view,view,"initWithFrame:@",@rect)
            CocoaMessage(0,win,"setContentView:",view)
        EndIf
       
        If center
            CocoaMessage(0,win,"center")
        EndIf
        CocoaMessage(0,win,"update")
        CocoaMessage(0,win,"display")
     
    EndIf
    ProcedureReturn win
EndProcedure
Procedure OnBtnClick()
  PostEvent(#PB_Event_CloseWindow)
EndProcedure
ProcedureC PanelShouldCloseCallback(Object.I, Selector.I, Sender.I)
  PostEvent(#PB_Event_CloseWindow)
EndProcedure
NSPanel = Panel(100,300,500,300,"HUD Window", #NSUtilityWindowMask|
                                              #NSTitledWindowMask|
                                              #NSClosableWindowMask|
                                              #NSMiniaturizableWindowMask|
                                              ;#NSTexturedBackgroundWindowMask|
                                              ;#NSNonactivatingPanelMask|
                                              #NSResizableWindowMask|
                                              #NSHUDWindowMask)
                                         
;CocoaMessage(0, NSPanel, "setStyleMask:", #NSUtilityWindowMask|
;                                          #NSTitledWindowMask|
;                                          #NSClosableWindowMask|
;                                          #NSMiniaturizableWindowMask|
;                                          ;#NSTexturedBackgroundWindowMask|
;                                          #NSResizableWindowMask)
;CocoaMessage(0, NSPanel, "setFloatingPanel:",#YES)
;CocoaMessage(0, NSPanel, "setShowsResizeIndicator:",#YES)
CocoaMessage(0, NSPanel, "setMovableByWindowBackground:",#YES)
CocoaMessage(0, NSPanel, "setLevel:",#NSFloatingWindowLevel) ; stay on top
UseGadgetList( NSPanel )
ButtonGadget(0,340,5,150,25,"Exit")
;Filter  = CocoaMessage(0, 0, "CIFilter filterWithName:$", @"CIColorMonochrome") ; create a CIColorMonochrome filter
;CocoaMessage(0, Filter, "setDefaults")                                          ; set the default values for the filter
;Color = CocoaMessage(0, 0, "CIColor colorWithString:$", @"0.1 0.1 0.1 1.0")     ; create a CIColor object from a RGBA string
;CocoaMessage(0, Filter, "setValue:", Color, "forKey:$", @"inputColor")          ; assign the color to the filter
;FilterArray = CocoaMessage(0, 0, "NSArray arrayWithObject:", Filter)            ; create an array with only the filter
 
;Button = GadgetID(0)
;CocoaMessage(0, Button, "setWantsLayer:", #YES)                                 ; the gadget needs a layer for the filter to work
;CocoaMessage(0, Button, "setContentFilters:", FilterArray)                      ; set the filter Array
;// Field 1
TextGadget(2,10,250,250,20,"Field 1:"): SetGadgetColor(2, #PB_Gadget_FrontColor, $FFFFFF)
StringGadget(3,65,252,100,20,""): SetGadgetColor(3, #PB_Gadget_FrontColor, $FFFFFF): SetGadgetColor(3, #PB_Gadget_BackColor, $555555)
;// Field 2
TextGadget(4,10,220,250,20,"Field 2:"): SetGadgetColor(4, #PB_Gadget_FrontColor, $FFFFFF)
StringGadget(5,65,222,100,20,""): SetGadgetColor(5, #PB_Gadget_FrontColor, $FFFFFF): SetGadgetColor(5, #PB_Gadget_BackColor, $555555)
;// Option Gadgets
OptionGadget(6,10,190,100,20,"Option 1"): SetGadgetColor(6, #PB_Gadget_FrontColor, $FFFFFF): SetGadgetColor(6, #PB_Gadget_BackColor, $555555)
OptionGadget(7,120,190,100,20,"Option 2"): SetGadgetColor(7, #PB_Gadget_FrontColor, $FFFFFF): SetGadgetColor(7, #PB_Gadget_BackColor, $555555)
;// Circular Slider
TrackBarGadget(8,250,240,36,36,0,12)
Cell = CocoaMessage(0, GadgetID(8), "cell"): SetGadgetColor(8, #PB_Gadget_FrontColor, $FFFFFF): SetGadgetColor(8, #PB_Gadget_BackColor, $555555)
CocoaMessage(8, Cell, "setSliderType:", 1); circular slider
CocoaMessage(8, Cell, "setNumberOfTickMarks:", 12)
CocoaMessage(8, Cell, "setAllowsTickMarkValuesOnly:", #YES)
;// ListViewGadget
ListViewGadget(9,10,60,200,120): SetGadgetColor(9, #PB_Gadget_FrontColor, $FFFFFF): SetGadgetColor(9, #PB_Gadget_BackColor, $555555)
For a=1 To 12
  AddGadgetItem(9,-1,"Item " + Str(a) +" of the ListView")
Next
SetGadgetState(9,4)
;// Horizontal Scrollbar
ScrollBarGadget(10,230,42,150,20,0,100,30)
SetGadgetState(10,50)
;// Vertical Scrollbar
ScrollBarGadget(11,380,42,20,150,0,100,30)
SetGadgetState(11,100)
BindGadgetEvent(0,@OnBtnClick())
class_addMethod(CocoaMessage(0, NSPanel, "class"),
  sel_registerName("windowShouldClose:"), @PanelShouldCloseCallback(), "v@:@")
CocoaMessage(0, WindowID(w1), "setDelegate:", AppDelegate)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindowCode: Select all
Procedure.s InputRequesterEx(Title.s, Info.s, DefaultInput.s = "")
  Protected.i Alert, InputField, Frame.NSRect
  Frame\size\width = 300
  Frame\size\height = 24
  InputField = CocoaMessage(0, CocoaMessage(0, CocoaMessage(0, 0, "NSTextField alloc"), "initWithFrame:@", Frame), "autorelease")
  CocoaMessage(0, InputField, "setStringValue:$", @DefaultInput)
  Alert = CocoaMessage(0, CocoaMessage(0, 0, "NSAlert new"), "autorelease")
  CocoaMessage(0, Alert, "setMessageText:$", @Title)
  CocoaMessage(0, Alert, "setInformativeText:$", @Info)
  CocoaMessage(0, Alert, "addButtonWithTitle:$", @"OK")    
  CocoaMessage(0, Alert, "addButtonWithTitle:$", @"Cancel")
  CocoaMessage(0, Alert, "setAccessoryView:", InputField)
  If CocoaMessage(0, Alert, "runModal") = 1000
    ProcedureReturn PeekS(CocoaMessage(0, CocoaMessage(0, InputField, "stringValue"), "UTF8String"), -1, #PB_UTF8)
  Else
    ProcedureReturn ""
  EndIf
EndProcedure
Debug InputRequesterEx("Title", "Informative text", "Default input")Code: Select all
Global Workspace.i = CocoaMessage(0, 0, "NSWorkspace sharedWorkspace") ; for MessageRequesterEx
Procedure MessageRequesterEx(Title.s, Info.s,type.s="'note'",defaultbutton=1,buttonone.s="Ok",buttontwo.s="",buttonthree.s="",buttonfour.s="",buttonfive.s="") ; max 5 buttons
    Protected.i Alert, Frame.NSRect,numberbuttons=0,button
    If FindString("'APPL''caut''note''stop'",type,1)=0 : Debug "no type":EndIf
    Frame\size\width = 300
    Frame\size\height = 24
    Alert = CocoaMessage(0, CocoaMessage(0, 0, "NSAlert new"), "autorelease")
    CocoaMessage(0, Alert, "setMessageText:$", @Title)
    CocoaMessage(0, Alert, "setInformativeText:$", @Info)
    CocoaMessage(0, Alert, "setIcon:", CocoaMessage(0, Workspace, "iconForFileType:$", @Type))
        
    If buttonfive
        CocoaMessage(0, Alert, "addButtonWithTitle:$", @buttonfive) 
        numberbuttons+1
    EndIf
    If buttonfour
        CocoaMessage(0, Alert, "addButtonWithTitle:$", @buttonfour)
        numberbuttons+1
    EndIf
    If buttonthree
        CocoaMessage(0, Alert, "addButtonWithTitle:$", @buttonthree)
        numberbuttons+1
    EndIf
    If buttontwo
        CocoaMessage(0, Alert, "addButtonWithTitle:$", @buttontwo) 
        numberbuttons+1
    EndIf
    CocoaMessage(0, Alert, "addButtonWithTitle:$", @buttonone)
        Button = CocoaMessage(0, CocoaMessage(0, Alert, "buttons"), "objectAtIndex:",numberbuttons-defaultbutton+1)
        CocoaMessage(0, CocoaMessage(0, Alert, "window"), "setDefaultButtonCell:", CocoaMessage(0, Button ,"cell"))
    ProcedureReturn 1001+numberbuttons-CocoaMessage(0, Alert, "runModal")
EndProcedure
MessageRequesterEx("Title","Information")
MessageRequesterEx("Title","Information","'caut'")
buttonselected=MessageRequesterEx("Title","Information","'note'",1,"Cancel","Yes","No") : Debug buttonselected
buttonselected=MessageRequesterEx("Title","Information","'caut'",2,"Cancel","Yes","No") : Debug buttonselected
buttonselected=MessageRequesterEx("Title","Information","'stop'",3,"Cancel","Yes","No") : Debug buttonselected