[PB Cocoa] Methods, Tips & Tricks

Mac OSX specific forum
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

Toggle animation in moving ProgressBar on and off (only possible in Snow Leopard or older):

Code: Select all

If OSVersion() > #PB_OS_MacOSX_10_6
  MessageRequester("Info", "Sorry, but stopping a progressbar's animation is no longer possible beginning with Lion...")
  End
EndIf

OpenWindow(0, 270, 100, 320, 100, "Toggle ProgressBar animation")
ProgressBarGadget(0, 10, 20, 300, 30, 0, 100)
SetGadgetState(0, 0)
ButtonGadget(1, 90, 65, 130, 25, "Stop Animation")
AnimationEnabled = #True
AddWindowTimer(0, 0, 100)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Timer
      CurrentValue = GetGadgetState(0)

      If CurrentValue = 100
        SetGadgetState(0, 0)
      Else
        SetGadgetState(0, CurrentValue + 1)

        If AnimationEnabled = #False
          CocoaMessage(0, GadgetID(0), "stopAnimation:$", @"self")
        EndIf
      EndIf
    Case #PB_Event_Gadget
      If EventGadget() = 1 And EventType() = #PB_EventType_LeftClick
        AnimationEnabled ! 1

        If AnimationEnabled
          CocoaMessage(0, GadgetID(0), "startAnimation:$", @"self")
          SetGadgetText(1, "Stop Animation")
        Else
          CocoaMessage(0, GadgetID(0), "stopAnimation:$", @"self")
          SetGadgetText(1, "Start Animation")
        EndIf
      EndIf
  EndSelect
ForEver
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

Change indentation of subitems in TreeGadget:

Code: Select all

EnableExplicit

Define i.I
Define Indentation.CGFloat

OpenWindow(0, 270, 100, 200, 220, "Change Indentation")
TreeGadget(0, 10, 10, WindowWidth(0) - 20, 100)
AddGadgetItem (0, -1, "Item 1", 0, 0)

For i = 1 To 3
  AddGadgetItem (0, -1, "Subitem " + Str(i), 0, 1)
Next i

SetGadgetItemState(0, 0, #PB_Tree_Expanded)

Frame3DGadget(1, 8, GadgetY(0) + GadgetHeight(0) + 10, WindowWidth(0) - 16, 90, "Indentation:")
TrackBarGadget(2, GadgetX(1) + 11, GadgetY(1) + 30, GadgetWidth(1) - 22, 23, 0, 50, #PB_TrackBar_Ticks)
CocoaMessage(0, GadgetID(2), "setAllowsTickMarkValuesOnly:", #YES)
TextGadget(3, GadgetX(1) + 10, GadgetY(2) + GadgetHeight(2) + 5, GadgetWidth(1) - 10, 20, "0    10    20    30    40    50")

; ----- Read current indentation and set TrackBar to that value
CocoaMessage(@Indentation, GadgetID(0), "indentationPerLevel")
SetGadgetState(2, Int(Indentation))

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = 2
        Indentation = GetGadgetState(2)
        ; ----- Set new indentation
        CocoaMessage(0, GadgetID(0), "setIndentationPerLevel:@", @Indentation)
      EndIf
  EndSelect
ForEver
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

Change frame around cells in a TreeGadget:

Code: Select all

EnableExplicit

Enumeration
  #FrameNone
  #FrameBezeled
  #FrameBordered
EndEnumeration

Procedure ChangeCellFrame(TreeGadgetID.I, ColumnIndex.I, FrameStyle.I)
  Protected CellObject.I
  Protected ColumnObject.I
  Protected ColumnObjectArray.I

  CocoaMessage(@ColumnObjectArray, GadgetID(TreeGadgetID), "tableColumns")
  CocoaMessage(@ColumnObject, ColumnObjectArray, "objectAtIndex:", ColumnIndex)
  CellObject = CocoaMessage(0, ColumnObject, "dataCell")

  Select FrameStyle
    Case #FrameNone
      CocoaMessage(0, CellObject, "setBordered:", #NO)
    Case #FrameBezeled
      CocoaMessage(0, CellObject, "setBezeled:", #YES)
    Case #FrameBordered
      CocoaMessage(0, CellObject, "setBordered:", #YES)
  EndSelect

  ; ----- Redraw TreeGagdet contents to see change
  CocoaMessage(0, GadgetID(TreeGadgetID), "reloadData")
EndProcedure

Define i.I
Define RowHeight.CGFloat = 20

OpenWindow(0, 270, 100, 350, 180, "TreeGadget")
TreeGadget(0, 10, 10, WindowWidth(0) - 20, 95)
Frame3DGadget(1, 20, GadgetY(0) + GadgetHeight(0) + 10, WindowWidth(0) - 40, 50, "Cell frame:")
OptionGadget(2, 30, GadgetY(1) + 20, 90, 23, "None")
OptionGadget(3, 130, GadgetY(1) + 20, 90, 23, "Bezeled")
OptionGadget(4, 230, GadgetY(1) + 20, 90, 23, "Bordered")
SetGadgetState(2, #True)

AddGadgetItem (0, -1, "Item 1", 0, 0)

For i = 1 To 3
  AddGadgetItem (0, -1, "Subitem " + Str(i), 0, 1)
Next i

; ----- Increase row height to leave enough space for border 
CocoaMessage(0, GadgetID(0), "setRowHeight:@", @RowHeight)

; ----- Expand subitems
SetGadgetItemState(0, 0, #PB_Tree_Expanded)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 2
          ChangeCellFrame(0, 0, #FrameNone)
        Case 3
          ChangeCellFrame(0, 0, #FrameBezeled)
        Case 4
          ChangeCellFrame(0, 0, #FrameBordered)
      EndSelect
  EndSelect
ForEver
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: [PB Cocoa] Methods, Tips & Tricks

Post by wilbert »

Example of using target/action and notifications

Code: Select all

ImportC ""
  sel_registerName(str.p-ascii)
  class_addMethod(class, selector, imp, types.p-ascii)
EndImport

Global appDelegate = CocoaMessage(0, CocoaMessage(0, 0, "NSApplication sharedApplication"), "delegate")
Global delegateClass = CocoaMessage(0, appDelegate, "class")
Global notificationCenter = CocoaMessage(0, 0, "NSNotificationCenter defaultCenter")

PrototypeC ProtoCallback(sender)

ProcedureC ForwardAction(obj, sel, sender)
  Protected Callback.ProtoCallback = CocoaMessage(0, sender, "tag")
  Callback(sender)
EndProcedure

Global selForwardAction = sel_registerName("forwardAction:")
Global selNotificationCallback = sel_registerName("notificationCallback:")

class_addMethod(delegateClass, selForwardAction, @ForwardAction(), "v@:@")

Procedure SetTargetActionCallback(control, *cbfunction)
  CocoaMessage(0, control, "setTag:", *cbfunction)
  CocoaMessage(0, control, "setTarget:", appDelegate)
  CocoaMessage(0, control, "setAction:", selForwardAction)  
EndProcedure


; *** demo ***

ProcedureC NotificationCallback(obj, sel, notification)
  Protected notificationName = CocoaMessage(0, CocoaMessage(0, notification, "name"), "UTF8String")
  Debug PeekS(notificationName, -1, #PB_UTF8)
EndProcedure

class_addMethod(delegateClass, selNotificationCallback, @NotificationCallback(), "v@:@")

ProcedureC Callback(sender)
  Debug "TrackBarGadget 0"
EndProcedure
 
OpenWindow(0, 100, 100, 300, 200, "Test")
TrackBarGadget(0, 10, 10, 200, 20, 0, 100)

CocoaMessage(0, notificationCenter, "addObserver:", appDelegate, "selector:", selNotificationCallback, "name:", #Null, "object:", WindowID(0))
SetTargetActionCallback(GadgetID(0), @Callback())

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

CocoaMessage(0, notificationCenter, "removeObserver:", appDelegate)
PB 5.40+

Code: Select all

Global appDelegate = CocoaMessage(0, CocoaMessage(0, 0, "NSApplication sharedApplication"), "delegate")
Global delegateClass = CocoaMessage(0, appDelegate, "class")
Global notificationCenter = CocoaMessage(0, 0, "NSNotificationCenter defaultCenter")

PrototypeC ProtoCallback(sender)

ProcedureC ForwardAction(obj, sel, sender)
  Protected Callback.ProtoCallback = CocoaMessage(0, sender, "tag")
  Callback(sender)
EndProcedure

Global selForwardAction = sel_registerName_("forwardAction:")
Global selNotificationCallback = sel_registerName_("notificationCallback:")

class_addMethod_(delegateClass, selForwardAction, @ForwardAction(), "v@:@")

Procedure SetTargetActionCallback(control, *cbfunction)
  CocoaMessage(0, control, "setTag:", *cbfunction)
  CocoaMessage(0, control, "setTarget:", appDelegate)
  CocoaMessage(0, control, "setAction:", selForwardAction)  
EndProcedure


; *** demo ***

ProcedureC NotificationCallback(obj, sel, notification)
  Protected notificationName = CocoaMessage(0, CocoaMessage(0, notification, "name"), "UTF8String")
  Debug PeekS(notificationName, -1, #PB_UTF8)
EndProcedure

class_addMethod_(delegateClass, selNotificationCallback, @NotificationCallback(), "v@:@")

ProcedureC Callback(sender)
  Debug "TrackBarGadget 0"
EndProcedure
 
OpenWindow(0, 100, 100, 300, 200, "Test")
TrackBarGadget(0, 10, 10, 200, 20, 0, 100)

CocoaMessage(0, notificationCenter, "addObserver:", appDelegate, "selector:", selNotificationCallback, "name:", #Null, "object:", WindowID(0))
SetTargetActionCallback(GadgetID(0), @Callback())

Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow

CocoaMessage(0, notificationCenter, "removeObserver:", appDelegate)
Last edited by wilbert on Fri Oct 09, 2015 7:07 pm, edited 1 time in total.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: [PB Cocoa] Methods, Tips & Tricks

Post by wilbert »

Get an icon image (32 x 32 px) for a specific file type.
The example uses txt but you can also use other types of course.

Code: Select all

If OpenWindow(0, 0, 0, 64, 64, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  ImageID = CocoaMessage(0, CocoaMessage(0, 0, "NSWorkspace sharedWorkspace"), "iconForFileType:$", @"txt")
  ImageGadget(0, 16, 16, 32, 32, ImageID)
  
  Repeat
    Event = WaitWindowEvent()
  Until Event = #PB_Event_CloseWindow
  
EndIf
Windows (x64)
Raspberry Pi OS (Arm64)
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: [PB Cocoa] Methods, Tips & Tricks

Post by wilbert »

Here's an example of working with NSUserDefaults instead of a PureBasic Preference file.

Code: Select all

Global UserDefaults = CocoaMessage(0, 0, "NSUserDefaults standardUserDefaults")

Procedure SynchronizeUserDefaults()
  CocoaMessage(0, UserDefaults, "synchronize")
EndProcedure

Procedure SetUserDefaultString(Key.s, Value.s)
  CocoaMessage(0, UserDefaults, "setObject:$", @Value, "forKey:$", @Key) 
EndProcedure

Procedure.s GetUserDefaultString(Key.s)
  Protected NSString = CocoaMessage(0, UserDefaults, "stringForKey:$", @Key)
  If NSString
    ProcedureReturn PeekS(CocoaMessage(0, NSString, "UTF8String"), -1, #PB_UTF8)
  Else
    ProcedureReturn ""  
  EndIf
EndProcedure

Procedure SetUserDefaultInteger(Key.s, Value.i)
  CocoaMessage(0, UserDefaults, "setInteger:", Value, "forKey:$", @Key) 
EndProcedure

Procedure.i GetUserDefaultInteger(Key.s)
  ProcedureReturn CocoaMessage(0, UserDefaults, "integerForKey:$", @Key) 
EndProcedure



; *** demo ***

If OpenWindow(0, 0, 0, 322, 205, "User defaults demo", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  StringGadget(0, 8,  10, 306, 20, "")
  StringGadget(1, 8,  35, 306, 20, "", #PB_String_Numeric)
  
  SetGadgetText(0, GetUserDefaultString("Gadget0"))
  SetGadgetText(1, Str(GetUserDefaultInteger("Gadget1")))
  
  Repeat
    Event = WaitWindowEvent()
    If Event = #PB_Event_Gadget
      Select EventGadget()
          
        Case 0
          SetUserDefaultString("Gadget0", GetGadgetText(0))
          
        Case 1
          SetUserDefaultInteger("Gadget1", Val(GetGadgetText(1)))
          
      EndSelect
    EndIf
  Until Event = #PB_Event_CloseWindow
  
EndIf

SynchronizeUserDefaults(); Synchronize to disk
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

It doesn't need any API function to open the finder and preselect a folder or file as jamirokwai has already demonstrated. For example to open the finder and preselect TextEdit you just have to code this one line:

Code: Select all

RunProgram("open", "-R " + "/Applications/TextEdit.app", "")
But to preselect multiple files you have to undertake some greater effort:

Code: Select all

; Needs at least MacOS X 10.6 to work!

EnableExplicit

Procedure CreateFileArray(List Filename.S())
  Protected FileArray.I
  Protected Filename.S
  Protected FileURL.I

  FileArray = CocoaMessage(0, 0, "NSMutableArray arrayWithCapacity:", ListSize(Filename()))
  
  If FileArray
    ForEach Filename()
      Filename = Filename()
      FileURL = CocoaMessage(0, 0, "NSURL fileURLWithPath:$", @Filename, "isDirectory:", #False)
      CocoaMessage(0, FileArray, "addObject:", FileURL)
    Next
  EndIf

  ProcedureReturn FileArray
EndProcedure

Define FileArray.I
Define Workspace.I

NewList Filename.S()

AddElement(Filename())
Filename() = "/Applications/Safari.app"
AddElement(Filename())
Filename() = "/Applications/TextEdit.app"
AddElement(Filename())
Filename() = "/Applications/Time Machine.app"

FileArray = CreateFileArray(Filename())

If FileArray
  Workspace = CocoaMessage(0, 0, "NSWorkspace sharedWorkspace")
  CocoaMessage(0, Workspace, "activateFileViewerSelectingURLs:", FileArray)
EndIf
gwhuntoon
New User
New User
Posts: 9
Joined: Sun Mar 03, 2013 2:50 pm
Location: Muskegon, MI USA

Re: [PB Cocoa] Methods, Tips & Tricks

Post by gwhuntoon »

Cycle through button bezel styles

Example:

Code: Select all

Global cmd_1, lbl_1, spn_1, wnd_1

Dim ButtonStyle.s(15)                                                                 ;Array to store bezel styles

;Instantiate bezel style array
ButtonStyle(1) = "NSRoundedBezelStyle"
Buttonstyle(2) = "NSRegularSquareBezelStyle"
Buttonstyle(3) = "NSThickSquareBezelStyle"
Buttonstyle(4) = "NSThickerSquareBezelStyle"
Buttonstyle(5) = "NSDisclosureBezelStyle"
Buttonstyle(6) = "NSShadowlessSquareBezelStyle"
Buttonstyle(7) = "NSCircularBezelStyle"
Buttonstyle(8) = "NSTexturedSquareBezelStyle"
Buttonstyle(9) = "NSHelpButtonBezelStyle"
Buttonstyle(10) = "NSSmallSquareBezelStyle"
Buttonstyle(11) = "NSTexturedRoundedBezelStyle"
Buttonstyle(12) = "NSRoundRectBezelStyle"
Buttonstyle(13) = "NSRecessedBezelStyle"
Buttonstyle(14) = "NSRoundedDisclosureBezelStyle"
Buttonstyle(15) = "NSInlineBezelStyle"

If OpenWindow(0, 0, 0, 320, 150, "Button Bezel Styles", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  spn_1 = SpinGadget (#PB_Any, 290, 51, 18, 25, 1, 15, #PB_Spin_Numeric)                ;Create a spin gadget
  cmd_1 = ButtonGadget(#PB_Any, 35, 50, 250, 28, "")                                    ;Create a button gadget
  lbl_1 = TextGadget(#PB_Any, 35, 90, 250, 20, "NSRoundedBezelStyle", #PB_Text_Center)  ;Create a label gadget
  SetGadgetState (spn_1, 1): SetGadgetText(spn_1, "1")                                  ;Set the initial state of the spin gadget
    Repeat
      Event = WaitWindowEvent()
      If Event = #PB_Event_Gadget
        If EventGadget() = spn_1                                                        ;Was the spin gadget clicked?
          CocoaMessage(0, GadgetID(cmd_1), "setBezelStyle:", GetGadgetState(spn_1))     ;Cycle through the button bezel styles
          SetGadgetText(lbl_1, ButtonStyle(GetGadgetState(spn_1)))                      ;Display the style in the label
        EndIf
      EndIf
    Until Event = #PB_Event_CloseWindow
EndIf
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: [PB Cocoa] Methods, Tips & Tricks

Post by wilbert »

Disable selection highlighting of a ListIconGadget (OS X 10.6+)

Code: Select all

OpenWindow(0, 200, 100, 430, 100, "Disable highlight example")

ListIconGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20, "Name", 110)
CocoaMessage(0, GadgetID(0), "setSelectionHighlightStyle:", -1); ** don't highlight selection **

AddGadgetColumn(0, 1, "Address", GadgetWidth(0) - GetGadgetItemAttribute(0, 0, #PB_ListIcon_ColumnWidth) - 8)
AddGadgetItem(0, -1, "Harry Rannit" + #LF$ + "12 Parliament Way, Battle Street, By the Bay")
AddGadgetItem(0, -1, "Ginger Brokeit" + #LF$ + "130 PureBasic Road, BigTown, CodeCity")
AddGadgetItem(0, -1, "Didi Foundit" + #LF$ + "321 Logo Drive, Mouse House, Downtown")

Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
J. Baker
Addict
Addict
Posts: 2178
Joined: Sun Apr 27, 2003 8:12 am
Location: USA
Contact:

Re: [PB Cocoa] Methods, Tips & Tricks

Post by J. Baker »

Insert text at the cursor position.

Code: Select all

If OpenWindow(0, 0, 0, 322, 180, "EditorGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    EditorGadget(0, 8, 8, 306, 133)
    For a = 0 To 5
      AddGadgetItem(0, a, "Line "+Str(a))
    Next
    
    SetActiveGadget(0)
    
    ButtonGadget(1, 115, 150, 100, 25, "Insert Text")
    
 Repeat
   
   Event = WaitWindowEvent()
  
  If Event = #PB_Event_Gadget

      Select EventGadget()
          
        Case 1
          CocoaMessage(0, GadgetID(0), "insertText:$", @" My inserted test!")
          
      EndSelect
      
  EndIf
    
 Until Event = #PB_Event_CloseWindow
    
EndIf
www.posemotion.com

PureBasic Tools for OS X: PureMonitor, plist Tool, Data Maker & App Chef

Mac: 10.13.6 / 1.4GHz Core 2 Duo / 2GB DDR3 / Nvidia 320M
PC: Win 7 / AMD 64 4000+ / 3GB DDR / Nvidia 720GT


Even the vine knows it surroundings but the man with eyes does not.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: [PB Cocoa] Methods, Tips & Tricks

Post by wilbert »

Set the text color of specific areas of an EditorGadget

Code: Select all

Procedure SetTextColorABGR(EditorGadget, Color, StartPosition, Length = -1, BackColor = #NO)
  Protected.CGFloat r,g,b,a
  Protected range.NSRange, textStorage.i
  If StartPosition > 0
    textStorage = CocoaMessage(0, GadgetID(EditorGadget), "textStorage")
    range\location = StartPosition - 1
    range\length = CocoaMessage(0, textStorage, "length") - range\location
    If range\length > 0
      If Length >= 0 And Length < range\length
        range\length = Length
      EndIf
      r = Red(Color) / 255
      g = Green(Color) / 255
      b = Blue(Color) / 255
      a = Alpha(Color) / 255
      Color = CocoaMessage(0, 0, "NSColor colorWithDeviceRed:@", @r, "green:@", @g, "blue:@", @b, "alpha:@", @a)
      If BackColor
        CocoaMessage(0, textStorage, "addAttribute:$", @"NSBackgroundColor", "value:", Color, "range:@", @range)
      Else
        CocoaMessage(0, textStorage, "addAttribute:$", @"NSColor", "value:", Color, "range:@", @range)
      EndIf
    EndIf
  EndIf
EndProcedure


; test the procedure

If OpenWindow(0, 0, 0, 322, 150, "EditorGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  EditorGadget(0, 8, 8, 306, 133)
  SetGadgetText(0, "This is a test string to test if coloring" + #CRLF$ + "specific areas will work")
  
  SetTextColorABGR(0, $ff008000, 1); make entire text green
  SetTextColorABGR(0, $ff000080, 1, 7); make first seven characters red
  SetTextColorABGR(0, $ff00f0ff, 1, 4, #YES); set background color of first four characters 
      
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
The same but for TextGadget

Code: Select all

Procedure SetTextColorABGR(TextGadget, Color, StartPosition, Length = -1, BackColor = #NO)
  Protected.CGFloat r,g,b,a
  Protected range.NSRange, MAString.i
  If StartPosition > 0
    
    MAString = CocoaMessage(0, CocoaMessage(0, 0, "NSMutableAttributedString alloc"), "initWithAttributedString:", 
                            CocoaMessage(0, GadgetID(TextGadget), "attributedStringValue"))
    
    range\location = StartPosition - 1
    range\length = CocoaMessage(0, MAString, "length") - range\location
    If range\length > 0
      If Length >= 0 And Length < range\length
        range\length = Length
      EndIf
      r = Red(Color) / 255
      g = Green(Color) / 255
      b = Blue(Color) / 255
      a = Alpha(Color) / 255
      Color = CocoaMessage(0, 0, "NSColor colorWithDeviceRed:@", @r, "green:@", @g, "blue:@", @b, "alpha:@", @a)
      If BackColor
        CocoaMessage(0, MAString, "addAttribute:$", @"NSBackgroundColor", "value:", Color, "range:@", @range)
      Else
        CocoaMessage(0, MAString, "addAttribute:$", @"NSColor", "value:", Color, "range:@", @range)
      EndIf
    EndIf
    CocoaMessage(0, GadgetID(TextGadget), "setAttributedStringValue:", MAString)
  EndIf
EndProcedure


; test the procedure

If OpenWindow(0, 0, 0, 322, 150, "TextGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  TextGadget(0, 8, 8, 306, 133, "")
  SetGadgetText(0, "This is a test string to test if coloring" + #CRLF$ + "specific areas will work")
  
  SetTextColorABGR(0, $ff008000, 1); make entire text green
  SetTextColorABGR(0, $ff000080, 1, 7); make first seven characters red
  SetTextColorABGR(0, $ff00f0ff, 1, 4, #YES); set background color of first four characters 
      
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
EndIf
Last edited by wilbert on Mon Aug 17, 2015 3:27 pm, edited 1 time in total.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

Display an alert (MessageRequester with OK button) specifying a predefined icon:

Code: Select all

EnableExplicit

#kOnSystemDisk = -32768
#kSystemIconsCreator = $6D616373

; ----- Predefined alert icons
#kGenericApplicationIcon =  $4150504C ; 'APPL'
#kAlertCautionIcon       =  $63617574 ; 'caut'
#kAlertNoteIcon          = $6E6F7465 ; 'note'
#kAlertStopIcon          = $73746F70 ; 'stop'

ImportC ""
  GetIconRef(StartVolume.W, Creator.L, IconID.L, *IconRef)
  ReleaseIconRef(IconRef.I)
EndImport

Procedure MessageRequesterEx(Title.S, Info.S, IconID.L)
  Protected Alert.I
  Protected IconRef.L
  Protected Image.I

  Alert = CocoaMessage(0, CocoaMessage(0, 0, "NSAlert new"), "autorelease")
  CocoaMessage(0, Alert, "setMessageText:$", @Title)
  CocoaMessage(0, Alert, "setInformativeText:$", @Info)
  
  If GetIconRef(#kOnSystemDisk, #kSystemIconsCreator, IconID, @IconRef) = 0
    Image = CocoaMessage(0, 0, "NSImage alloc")
    CocoaMessage(0, Image, "initWithIconRef:", IconRef)
    CocoaMessage(0, Alert, "setIcon:@", @Image)
    CocoaMessage(0, Alert, "runModal")
    CocoaMessage(0, Image, "release")
    ReleaseIconRef(IconRef)
  EndIf
EndProcedure

MessageRequesterEx("Icon demo 1", "Requester with app icon", #kGenericApplicationIcon)
MessageRequesterEx("Icon demo 2", "Requester with caution icon", #kAlertCautionIcon)
MessageRequesterEx("Icon demo 3", "Requester with note icon", #kAlertNoteIcon)
MessageRequesterEx("Icon demo 4", "Requester with stop icon", #kAlertStopIcon)
Update 1: I have added the ReleaseIconRef() function to properly decrease the icon reference count after displaying the requester and thus closing a memory leak.

Update 2: Wilbert sent me a PM with a simplified solution which doesn't need anymore to import the outdated Carbon functions. Thank you for that nice hint, Wilbert!

Code: Select all

EnableExplicit

Global Workspace.i = CocoaMessage(0, 0, "NSWorkspace sharedWorkspace")

Procedure MessageRequesterEx(Title.s, Info.s, Type.s)
  Protected Alert.i = 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))
  CocoaMessage(0, Alert, "runModal")
EndProcedure

MessageRequesterEx("Icon demo 1", "Requester with app icon", "'APPL'")
MessageRequesterEx("Icon demo 2", "Requester with caution icon", "'caut'")
MessageRequesterEx("Icon demo 3", "Requester with note icon", "'note'")
MessageRequesterEx("Icon demo 4", "Requester with stop icon", "'stop'")
User avatar
Shardik
Addict
Addict
Posts: 1989
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

Get description of your time zone, whether daylight saving is activated, if yes the current time offset, and the date of the next daylight saving transition:

Code: Select all

EnableExplicit

Define DaylightSaving.I
Define Info.S
Define LastTransitionDate.D
Define NextTransitionDate.D
Define TimeOffsetInSeconds.D
Define TimeZoneObject.I

TimeZoneObject = CocoaMessage(0, 0, "NSTimeZone systemTimeZone")
CocoaMessage(@DaylightSaving, TimeZoneObject, "isDaylightSavingTime")

If DaylightSaving
  Info + "Daylight saving is activated." + #CR$
  CocoaMessage(@TimeOffsetInSeconds, TimeZoneObject, "daylightSavingTimeOffset")
  Info + "Time offset = " + Str(Int(TimeOffsetInSeconds) / 60) + " minutes" + #CR$
Else
  Info + "Daylight saving is deactivated."
EndIf

Info + "Time zone description: " + PeekS(CocoaMessage(0, CocoaMessage(0, TimeZoneObject, "description"), "UTF8String"), -1, #PB_UTF8) + #CR$

CocoaMessage(@NextTransitionDate, CocoaMessage(0, TimeZoneObject, "nextDaylightSavingTimeTransition"), "timeIntervalSince1970")
Info + "Next daylight saving transition: " + FormatDate("%yyyy-%mm-%dd %hh:%ii:%ss", Int(NextTransitionDate)) + #CR$

MessageRequester("Time zone infos", Info)
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: [PB Cocoa] Methods, Tips & Tricks

Post by wilbert »

Get all file names from a directory including all files in all of its subdirectories.

Code: Select all

Dir.s = #PB_Compiler_Home + "purelibraries"

FileManager = CocoaMessage(0, 0, "NSFileManager defaultManager")
DirEnum = CocoaMessage(0, FileManager, "enumeratorAtPath:$", @Dir)

File = CocoaMessage(0, DirEnum, "nextObject")
While File

  FileName.s = PeekS(CocoaMessage(0, File, "UTF8String"), -1, #PB_UTF8)
  Debug FileName
  
  File = CocoaMessage(0, DirEnum, "nextObject")
Wend
Windows (x64)
Raspberry Pi OS (Arm64)
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: [PB Cocoa] Methods, Tips & Tricks

Post by wilbert »

Maybe not very useful for most users but this code example moves a PureBasic created window to a second screen if you have one and makes it fit the screen.

Code: Select all

Global Dim Screens.NSRect(0)

Procedure GetAvailableScreens()
  Protected ScreenArray = CocoaMessage(0, 0, "NSScreen screens")
  Protected i, NumScreens = CocoaMessage(0, ScreenArray, "count")
  ReDim Screens(NumScreens - 1)
  While i < NumScreens
    CocoaMessage(@Screens(i), CocoaMessage(0, ScreenArray, "objectAtIndex:", i), "frame")
    i + 1
  Wend
  ProcedureReturn NumScreens
EndProcedure

; test the code

NumScreens = GetAvailableScreens()
For i = 0 To NumScreens - 1
  Debug "Screen " + Str(i) + " : " + Str(Screens(i)\size\width) + " x " + Str(Screens(i)\size\height) + " px, offset x : " + Str(Screens(i)\origin\x)
Next

If NumScreens > 1
  OpenWindow(0, 0, 0, 0, 0, "PureBasic Window", #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
  CocoaMessage(0, WindowID(0), "setFrame:@", @Screens(1), "display:", #YES)
  
  Repeat
    Event = WaitWindowEvent()
  Until Event = #PB_Event_CloseWindow
  
EndIf
Windows (x64)
Raspberry Pi OS (Arm64)
Post Reply