[PB Cocoa] Methods, Tips & Tricks

Mac OSX specific forum
mrbungle
Enthusiast
Enthusiast
Posts: 118
Joined: Wed Dec 30, 2020 3:18 am

Re: [PB Cocoa] Methods, Tips & Tricks

Post by mrbungle »

Acknowledged. However, this code works fine on Big Sur and Monterey running on an Intel Mac using PB 6 or compiled apps on the Mac M1. I believe the issue is with the C backend of PB 6 using the native ARM version. Even functions like like NS.Size don't seem to work.
User avatar
mk-soft
Always Here
Always Here
Posts: 5409
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by mk-soft »

Please move it to bug reports "Bugs - C backend"
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
Shardik
Addict
Addict
Posts: 1991
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

I have modified my source code to sort ListIconGadget contents by clicking on the column header cell and displaying an ascending or descending icon to also work in PB 6.00 with Asm and C backend and in older PB versions (successfully tested on MacOS 11.7.2 'Big Sur' on an iMac 2019 with Intel x86-64):

Code: Select all

EnableExplicit

Structure TableEntry
  Name.S
  Address.S
EndStructure

Enumeration #PB_Event_FirstCustomValue
  #PB_Event_ListIcon_SortAscending
  #PB_Event_ListIcon_SortDescending
EndEnumeration

Define AppDelegate.I = CocoaMessage(0, CocoaMessage(0, 0,
  "NSApplication sharedApplication"), "delegate")
Define AscendingArrow.I
Define ColumnArray.I
Define DelegateClass.I = CocoaMessage(0, AppDelegate, "class")
Define DescendingArrow.I
Define i.I
Define LastSortColumn.I
Define SortColumn.I
Define SortIsAscending.I

NewList Table.TableEntry()

ProcedureC WillDisplayCell(Object.I, Selector.I, TableView.I, Cell.I, *Column,
  Row.I)
  Protected Column.I
  Protected CellText.S
  Protected ListIconID.I

  ListIconID = CocoaMessage(0, TableView, "tag")
  Column = CocoaMessage(0, CocoaMessage(0, TableView, "tableColumns"),
    "indexOfObject:", *Column)
  CocoaMessage(0, Cell, "_setVerticallyCentered:", #YES)
  CellText = GetGadgetItemText(ListIconID, Row, Column)
  CocoaMessage(0, Cell, "setStringValue:$", @CellText)
EndProcedure

ProcedureC LeftClickOnHeaderCellCallback(Object.I, Selector.I, View.I, Column.I)
  Shared SortColumn.I
  Shared SortIsAscending.I

  SortColumn = Column

  If SortIsAscending
    PostEvent(#PB_Event_ListIcon_SortDescending)
  Else
    PostEvent(#PB_Event_ListIcon_SortAscending)
  EndIf

  SortIsAscending ! 1
EndProcedure

Procedure SortListIcon(ListIconID.I, SortColumn.I)
  Shared Table()
  Shared SortIsAscending.I

  Protected ColumnIndex.I

  ColumnIndex = Val(PeekS(CocoaMessage(0, CocoaMessage(0, SortColumn,
    "identifier"), "UTF8String"), -1, #PB_UTF8))

  If SortIsAscending
    If ColumnIndex = 0
      SortStructuredList(Table(), #PB_Sort_Ascending,
        OffsetOf(TableEntry\Name), #PB_String)
    Else
      SortStructuredList(Table(), #PB_Sort_Ascending,
        OffsetOf(TableEntry\Address), #PB_String)
    EndIf
  Else
    If ColumnIndex = 0
      SortStructuredList(Table(), #PB_Sort_Descending,
        OffsetOf(TableEntry\Name), #PB_String)
    Else
      SortStructuredList(Table(), #PB_Sort_Descending,
        OffsetOf(TableEntry\Address), #PB_String)
    EndIf
  EndIf

  ClearGadgetItems(ListIconID)

  ForEach Table()
    AddGadgetItem(ListIconID, -1, Table()\Name + #LF$ + Table()\Address)
  Next
EndProcedure

OpenWindow(0, 200, 100, 450, 122, "Sort ListIcon with column click")
ListIconGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20, "Name",
  110)
AddGadgetColumn(0, 1, "Address", GadgetWidth(0) - GetGadgetItemAttribute(0, 0, #PB_ListIcon_ColumnWidth) - 8)
CocoaMessage(0, GadgetID(0), "sizeLastColumnToFit")

class_addMethod_(DelegateClass,
  sel_registerName_("tableView:willDisplayCell:forTableColumn:row:"),
  @WillDisplayCell(), "v@:@@@@")
class_addMethod_(DelegateClass,
  sel_registerName_("tableView:didClickTableColumn:"),
  @LeftClickOnHeaderCellCallback(), "v@:@@")
CocoaMessage(0, GadgetID(0), "setDelegate:", AppDelegate)

For i = 1 To 3
  AddElement(Table())
  Read.S Table()\Name
  Read.S Table()\Address
Next i

ForEach Table()
  AddGadgetItem(0, -1, Table()\Name + #LF$ + Table()\Address)
Next

AscendingArrow = CocoaMessage(0, CocoaMessage(0, 0, "NSImage imageNamed:$",
  @"NSAscendingSortIndicator"), "retain")
DescendingArrow = CocoaMessage(0, CocoaMessage(0, 0, "NSImage imageNamed:$",
  @"NSDescendingSortIndicator"), "retain")

CocoaMessage(@ColumnArray, GadgetID(0), "tableColumns")
CocoaMessage(@SortColumn, ColumnArray, "objectAtIndex:", 0)
LastSortColumn = SortColumn
SortIsAscending = #True
SortListIcon(0, SortColumn)
CocoaMessage(0, GadgetID(0), "setIndicatorImage:", AscendingArrow,
  "inTableColumn:", SortColumn)
CocoaMessage(0, GadgetID(0), "setDelegate:", AppDelegate)

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_ListIcon_SortAscending
      If SortColumn <> LastSortColumn
        CocoaMessage(0, GadgetID(0), "setIndicatorImage:", 0,
          "inTableColumn:", LastSortColumn)
        LastSortColumn = SortColumn
      EndIf
      SortListIcon(0, SortColumn)
      CocoaMessage(0, GadgetID(0), "setIndicatorImage:", AscendingArrow,
        "inTableColumn:", SortColumn)
    Case #PB_Event_ListIcon_SortDescending
      If SortColumn <> LastSortColumn
        CocoaMessage(0, GadgetID(0), "setIndicatorImage:", 0,
          "inTableColumn:", LastSortColumn)
        LastSortColumn = SortColumn
      EndIf

      SortListIcon(0, SortColumn)
      CocoaMessage(0, GadgetID(0), "setIndicatorImage:", DescendingArrow,
        "inTableColumn:", SortColumn)
  EndSelect
ForEver

End

DataSection
  Data.S "Harry Rannit"
  Data.S "12 Parliament Way, Battle Street, By the Bay"
  Data.S "Ginger Brokeit"
  Data.S "330 PureBasic Road, BigTown, CodeCity"
  Data.S "Didi Foundit"
  Data.S "231 Logo Drive, Mouse House, Downtown"
EndDataSection
User avatar
Shardik
Addict
Addict
Posts: 1991
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

I have modified my example to justify text in the columns of the ListIconGadget to work both in PB 5.73 and earlier and in PB 6.00 and newer. This has become necessary because Fred has changed internals of the cells in ListIconGadgets. In PB 6.0 Fred implemented the new PBIconTextCell which enables the display of both an icon and text in a single cell. But therefore unfortunately the old modifications don't work anymore.

This new example uses the old routines in PB 5.73 and earlier and a callback in PB 6.00 and newer. Furthermore the example was extended to change the justification of header cells (which didn't change in PB 6.00) separately from the column cells. The following example was successfully tested on these MacOS versions:
  • 'Big Sur' 11.7.3 with PB 5.73 and PB 6.00 (Asm and C backend)
  • 'Monterey' 12.6.3 with PB 5.73 and PB 6.00 (Asm and C backend)
  • 'Ventura' 13.2 and 13.2.1 with PB 5.73 and PB 6.00 (Asm and C backend)

Code: Select all

EnableExplicit

CompilerIf #PB_Compiler_Version >= 600
  Structure ListIconColumnFormatEntry
    ListIconID.I
    Array ColumnFormat.I(0) 
  EndStructure

  Define AppDelegate.I = CocoaMessage(0, CocoaMessage(0, 0,
    "NSApplication sharedApplication"), "delegate")
  Define DelegateClass.I = CocoaMessage(0, AppDelegate, "class")

  NewList ListIconColumnFormat.ListIconColumnFormatEntry()

  ProcedureC WillDisplayCell(Object.I, Selector.I, TableView.I, Cell.I,
    *Column, Row.I)
    Shared ListIconColumnFormat.ListIconColumnFormatEntry()

    Protected Column.I
    Protected CellText.S
    Protected ListIconID.I
  
    ListIconID = CocoaMessage(0, TableView, "tag")

    If ListSize(ListIconColumnFormat()) > 0
      ForEach ListIconColumnFormat()
        If ListIconColumnFormat()\ListIconID = ListIconID
          Column = CocoaMessage(0, CocoaMessage(0, TableView, "tableColumns"),
            "indexOfObject:", *Column)
          CocoaMessage(0, CocoaMessage(0, *Column, "dataCell"),
            "setAlignment:", ListIconColumnFormat()\ColumnFormat(Column))
          Break
        EndIf
      Next
    EndIf

    CocoaMessage(0, Cell, "_setVerticallyCentered:", #YES)
    CellText = GetGadgetItemText(ListIconID, Row, Column)
    CocoaMessage(0, Cell, "setStringValue:$", @CellText)
  EndProcedure
CompilerEndIf

Procedure SetListIconColumnJustification(ListIconID.I, ColumnIndex.I,
  Alignment.I, IsHeaderCell.I = #False)

  Protected ColumnHeaderCell.I
  Protected ColumnObject.I
  Protected ColumnObjectArray.I
  Protected ListIconIDFound.I

  CocoaMessage(@ColumnObjectArray, GadgetID(ListIconID), "tableColumns")
  CocoaMessage(@ColumnObject, ColumnObjectArray,
    "objectAtIndex:", ColumnIndex)

  If IsHeaderCell
    ; ----- Justify text of column header
    CocoaMessage(@ColumnHeaderCell, ColumnObject, "headerCell")
    CocoaMessage(0, ColumnHeaderCell, "setAlignment:", Alignment)
  Else
    CompilerIf #PB_Compiler_Version >= 600
      Shared AppDelegate.I
      Shared ListIconColumnFormat.ListIconColumnFormatEntry()

      If ListSize(ListIconColumnFormat()) = 0
        CocoaMessage(0, GadgetID(ListIconID), "setDelegate:", AppDelegate)
        AddElement(ListIconColumnFormat())
        ListIconColumnFormat()\ListIconID = ListIconID
        ReDim ListIconColumnFormat()\ColumnFormat(GetGadgetAttribute(0 +
          ListIconID, #PB_ListIcon_ColumnCount) - 1)
        ListIconColumnFormat()\ColumnFormat(ColumnIndex) = Alignment
      Else
        ForEach ListIconColumnFormat()
          If ListIconColumnFormat()\ListIconID = ListIconID
            ListIconColumnFormat()\ColumnFormat(ColumnIndex) = Alignment
            ListIconIDFound = #True
            Break
          EndIf
        Next

        If ListIconIDFound = #False
          CocoaMessage(0, GadgetID(ListIconID), "setDelegate:", AppDelegate)
          AddElement(ListIconColumnFormat())
          ListIconColumnFormat()\ListIconID = ListIconID
          ReDim ListIconColumnFormat()\ColumnFormat(GetGadgetAttribute(0 +
            ListIconID, #PB_ListIcon_ColumnCount) - 1)
          ListIconColumnFormat()\ColumnFormat(ColumnIndex) = Alignment
        EndIf
      EndIf
    CompilerElse
      CocoaMessage(0, CocoaMessage(0, ColumnObject, "dataCell"),
        "setAlignment:", Alignment)
    CompilerEndIf
  EndIf

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

Define OptionGadgetID.I

OpenWindow(0, 200, 100, 445, 220, "Change justification in 2nd column")
ListIconGadget(0, 5, 5, 435, 90, "Name", 95)
AddGadgetColumn(0, 1, "Address", 300)
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")

FrameGadget(1, 10, 95, WindowWidth(0) - 20, 50,
  "Justification of 2nd header column:")
OptionGadget(2, 20, 115, 70, 20, "Left")
OptionGadget(3, 330, 115, 70, 20, "Right")
OptionGadget(4, 180, 115, 70, 20, "Center")
SetGadgetState(2, #True)

FrameGadget(5, 10, 160, WindowWidth(0) - 20, 50,
  "Justification of 2nd column:")
OptionGadget(6, 20, 180, 70, 20, "Left")
OptionGadget(7, 330, 180, 70, 20, "Right")
OptionGadget(8, 180, 180, 70, 20, "Center")
SetGadgetState(6, #True)

CompilerIf #PB_Compiler_Version >= 600
  class_addMethod_(DelegateClass,
    sel_registerName_("tableView:willDisplayCell:forTableColumn:row:"),
    @WillDisplayCell(), "v@:@@@@")
CompilerEndIf

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      OptionGadgetID = EventGadget()

      Select OptionGadgetID
        Case 2 To 4
          SetListIconColumnJustification(0, 1, OptionGadgetID - 2, #True)
        Case 6 To 8
          SetListIconColumnJustification(0, 1, OptionGadgetID - 6)
      EndSelect
  EndSelect
ForEver
Last edited by Shardik on Wed Feb 15, 2023 9:34 pm, edited 2 times in total.
User avatar
Mindphazer
Enthusiast
Enthusiast
Posts: 346
Joined: Mon Sep 10, 2012 10:41 am
Location: Savoie

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Mindphazer »

Hello Shardik,

thanks a lot for your example, and the hard work to make it work on PB 6.00

When I click the "Center", the columns are right-justified
And when i click "Right", the columns are centered

I guess it's just a "quiproquo" :mrgreen:
MacBook Pro 14" M1 Pro - 16 Gb - MacOS 14 - Iphone 15 Pro Max - iPad at home
...and unfortunately... Windows at work...
User avatar
mk-soft
Always Here
Always Here
Posts: 5409
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by mk-soft »

The "CocoaMessage(0, GadgetID(ListIconID), "setDelegate:", AppDelegate)" destroy the Eventtype "PB_EventType_Change"
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
Shardik
Addict
Addict
Posts: 1991
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

Mindphazer wrote: Wed Feb 15, 2023 6:25 pm When I click the "Center", the columns are right-justified
And when i click "Right", the columns are centered
Sorry, but I can't confirm your findings. I have just also tested my example on MacOS 13.2 and 13.2.1 'Ventura' and it works like a charm in PB 6.00 with Asm and C backend.

Did you try my exact example? If not you probably changed "Right" (#NSRightTextAlignment = 1) and "Center" (#NSCenterTextAlignment = 2) because my example uses the GadgetIDs subtracting 6 for the alignment (in the FrameGadget #5) and the OptionGadget for "Right" is #7 but at the right side and "Center" is #8 and in the middle.
User avatar
Mindphazer
Enthusiast
Enthusiast
Posts: 346
Joined: Mon Sep 10, 2012 10:41 am
Location: Savoie

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Mindphazer »

Well, that's weird. I copied your example without changing any character.
I did it again, and have the same behaviour. If i select "Center" radio buttons, the columns are right justified
And if i select "Right" radio buttons, the columns are centered.
I'm on a Macbook Pro M1, macOS 13.2.1

I changed your Select this way to make it work as expected :

Code: Select all

Select OptionGadgetID
        Case 2
          SetListIconColumnJustification(0, 1, 0, #True)
        Case 3
          SetListIconColumnJustification(0, 1, 2, #True)
        Case 4
          SetListIconColumnJustification(0, 1, 1, #True)
        Case 6
          SetListIconColumnJustification(0, 1, 0)
        Case 7
          SetListIconColumnJustification(0, 1, 2)
        Case 8
          SetListIconColumnJustification(0, 1, 1)
      EndSelect
MacBook Pro 14" M1 Pro - 16 Gb - MacOS 14 - Iphone 15 Pro Max - iPad at home
...and unfortunately... Windows at work...
User avatar
Shardik
Addict
Addict
Posts: 1991
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

Mindphazer wrote: Thu Feb 16, 2023 12:16 am Well, that's weird. I copied your example without changing any character.
I did it again, and have the same behaviour. If i select "Center" radio buttons, the columns are right justified
And if i select "Right" radio buttons, the columns are centered.
I'm on a Macbook Pro M1, macOS 13.2.1
Maybe it's a problem with your ARM processor and the C backend compilation. Unfortunately I am only able to test on my iMacs with Intel processor. But thank you for your workaround!
Bmld756
User
User
Posts: 16
Joined: Mon Sep 19, 2022 3:30 pm

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Bmld756 »

Hello,

I found 'Sorting data by clicking a column header ' but the code don't work correctly. The text in the cell disappear, It is certainly too old.,

I found a solution so I post my code. I use selectcolumn and I switch off he highlights. I switch on the highlights if it is a row selected.
highlights

Code: Select all

EnableExplicit
Global quit,liste = 10 , event, Gadget

Structure Person
  nom.s
  prenom.s
  id.i
EndStructure

Global Dim tabTries.Person(2)
tabTries(0)\nom =  "Lager" : tabTries(0)\prenom = "Jules" : tabTries(0)\id = 7
tabTries(1)\nom =  "Lager" : tabTries(1)\prenom = "Jérome" : tabTries(1)\id = 12
tabTries(2)\nom =  "Garcia" : tabTries(2)\prenom = "Luca" : tabTries(2)\id = 2

Procedure TriAppel(Critere.s)
  Define i
  Debug Critere
  
  For i = 0 To 2
   Debug  tabTries(i)\nom +" "+tabTries(i)\prenom
 Next  
 
  Select Critere
    Case "Nom"
      SortStructuredArray(tabTries(), #PB_Sort_Ascending, OffsetOf(Person\nom), TypeOf(Person\nom))
    Case "Prenom"
      SortStructuredArray(tabTries(), #PB_Sort_Ascending, OffsetOf(Person\prenom), TypeOf(Person\prenom))
    Case "Id"
      SortStructuredArray(tabTries(), #PB_Sort_Ascending, OffsetOf(Person\id), TypeOf(Person\id))
  EndSelect 
  
EndProcedure

Procedure AfficheListe()
  Define i
  ; vide la liste
  For i = 0 To 2
    RemoveGadgetItem(liste, 0)
  Next
  ; lit les data
  For i = 0 To 2
    AddGadgetItem(liste, -1, tabTries(i)\nom + #LF$ + tabTries(i)\prenom + #LF$ + tabTries(i)\id) 
  Next
EndProcedure


OpenWindow(0, 200, 100, 600, 300, "Disable highlight example")
ListIconGadget(liste, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20, "Nom", 110)
AddGadgetColumn(liste, 1, "Prenom", 100)
AddGadgetColumn(liste, 2, "Id", 100)
CocoaMessage(0,  GadgetID(liste), "setAllowsColumnSelection:", #YES) ; autorise la selection de colonne
CocoaMessage(0, GadgetID(liste), "setSelectionHighlightStyle:", -1); -1 pas de surlignement  / surlignement   
AfficheListe()

Repeat
  event = WaitWindowEvent()
  Gadget = EventGadget();
  
  Select Event
    Case #PB_Event_CloseWindow
      quit = 1
    Case #PB_Event_Gadget     
      Select Gadget
          
        Case liste ; liste 
          Define SelectedColumn
          Select  EventType() 
            Case #PB_EventType_LeftDoubleClick                    ; Edite tireur
              Debug "ligne selectionnée"
            Case #PB_EventType_LeftClick   ; clic gauche 
              SelectedColumn = CocoaMessage(0,  GadgetID(Liste) , "selectedColumn")  
              Debug SelectedColumn
              If SelectedColumn = -1
                Debug "Aucune colonne de sélectionnée"
                CocoaMessage(0, GadgetID(liste), "setSelectionHighlightStyle:", 0); -1 pas de surlignement  / surlignement
              Else
                Debug "colonne  sélectionnée"
                ;selection d'une colonne > tri 
                CocoaMessage(0, GadgetID(liste), "setSelectionHighlightStyle:", -1); -1 pas de surlignement  / surlignement
                TriAppel(GetGadgetItemText(Gadget,-1,SelectedColumn))            ;Select SelectedColumn
                AfficheListe()
              EndIf
              
          EndSelect
      EndSelect
      
      EndSelect
    Until quit =1
IMAC 21.5 2012 Core I5 - 2.70 Ghz. 16 GB NVIDIA GeForce GT 640M 512 Mo. MacOs OCPL Sonoma 14.1.
MacBook Air M1 - 8Go - Sonoma 14.1

PureBasic 6.03 (MacOS X - x64)
User avatar
mk-soft
Always Here
Always Here
Posts: 5409
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by mk-soft »

SetClipboardFiles and GetClipboardFiles

Update v1.01.4
- Fix clear list

Code: Select all

;-TOP by mk-soft, v1.01.4 , 25.04.2023

Macro CocoaString(NSString)
  PeekS(CocoaMessage(0, NSString, "UTF8String"), -1, #PB_UTF8)
EndMacro

Procedure SetClipboardFile(FileName.s)
  Protected r1, pool, fileURL, objectsToCopy, pasteboard
  
  pool = CocoaMessage(0, 0, "NSAutoreleasePool new")
  
  fileURL = CocoaMessage(0, 0, "NSURL fileURLWithPath:$", @FileName)
  objectsToCopy = CocoaMessage(0, 0, "NSArray arrayWithObject:", fileURL)
  pasteboard = CocoaMessage(0, 0, "NSPasteboard generalPasteboard")
  CocoaMessage(0, pasteboard, "clearContents")
  r1 = CocoaMessage(0, pasteboard, "writeObjects:", objectsToCopy)
  
  CocoaMessage(0, pool, "release")
  
  ProcedureReturn r1
EndProcedure

Procedure SetClipboardFiles(List Files.s())
  Protected r1, pool, fileURL, objectsToCopy, pasteboard, filename.s, cnt
  
  pool = CocoaMessage(0, 0, "NSAutoreleasePool new")
  
  cnt = ListSize(Files())
  objectsToCopy = CocoaMessage(0, 0, "NSMutableArray arrayWithCapacity:", cnt)
  ForEach Files()
    filename = Files()
    fileURL = CocoaMessage(0, 0, "NSURL fileURLWithPath:$", @filename)
    CocoaMessage(0, objectsToCopy, "addObject:", fileURL)
  Next
  pasteboard = CocoaMessage(0, 0, "NSPasteboard generalPasteboard")
  CocoaMessage(0, pasteboard, "clearContents")
  r1 = CocoaMessage(0, pasteboard, "writeObjects:", objectsToCopy)
  
  CocoaMessage(0, pool, "release")
  
  ProcedureReturn r1
EndProcedure

Procedure GetClipboardFiles(List Files.s())
  Protected pool, number, dictionary, classURL, arrayObjects, pasteboard, urls, fileURL, string, cnt, index
  
  ClearList(Files())
  
  pool = CocoaMessage(0, 0, "NSAutoreleasePool new")
  
  number = CocoaMessage(0, 0, "NSNumber numberWithBool:", #True)
  dictionary = CocoaMessage(0, 0, "NSDictionary dictionaryWithObject:", number, "forKey:$", @"NSPasteboardURLReadingFileURLsOnlyKey")
  classURL = CocoaMessage(0, 0, "NSURL class")
  arrayObjects = CocoaMessage(0, 0, "NSArray arrayWithObject:", classURL)
  pasteboard = CocoaMessage(0, 0, "NSPasteboard generalPasteboard")
  urls = CocoaMessage(0, pasteboard, "readObjectsForClasses:", arrayObjects, "options:", dictionary)
  
  cnt = CocoaMessage(0, urls, "count")
  If cnt >= 1
    For index = 0 To cnt - 1
      fileURL = CocoaMessage(0, urls, "objectAtIndex:", index)
      string = CocoaMessage(0, fileURL, "path")
      AddElement(Files())
      Files() = CocoaString(string)
    Next
  EndIf
  
  CocoaMessage(0, pool, "release")
  
  ProcedureReturn cnt
EndProcedure

; ****

CompilerIf #PB_Compiler_IsMainFile
  
  #example = 2
  
  CompilerIf #example = 1
    
    filename.s = OpenFileRequester("", "", "", 0)
    If filename
      r1 = SetClipboardFile(filename)
      If r1 
        Debug "Ok"
      Else
        Debug "False"
      EndIf
    EndIf
    
  CompilerElseIf #example = 2
      
    Global NewList FileList.s()
    
    filename.s = OpenFileRequester("", "", "", 0, #PB_Requester_MultiSelection)
    While filename
      AddElement(FileList())
      FileList() = filename
      filename = NextSelectedFileName()
    Wend
    
    If FileSize(FileList())
      r1 = SetClipboardFiles(FileList())
      If r1 
        Debug "Ok"
      Else
        Debug "False"
      EndIf
    EndIf
  CompilerElseIf #example = 3
    
    Global NewList FileList.s()
    
    If GetClipboardFiles(FileList())
      ForEach FileList()
        Debug FileList()
      Next
    EndIf
  CompilerEndIf
  
CompilerEndIf
Last edited by mk-soft on Tue Apr 25, 2023 2:35 pm, edited 1 time in total.
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
Fred
Administrator
Administrator
Posts: 16690
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Fred »

Good work, as always.
User avatar
mk-soft
Always Here
Always Here
Posts: 5409
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by mk-soft »

New AppleScript with ErrorInfo

Code: Select all

;-TOP New AppleScript with ErrorInfo

; by mk-soft, v1.02.1, 06.05.2023

Macro CocoaString(NSString)
  PeekS(CocoaMessage(0, NSString, "UTF8String"), -1, #PB_UTF8)
EndMacro

Procedure.s AppleScript(Script.s)
  Protected retVal.s, strVal, numItems, i
  Protected *objPool
  Protected *objAppleScript, *objScript, *objEventDescriptor, *objDescriptor, *objErrorInfo
  Protected *enumerator, *key, *object
  
  *objPool = CocoaMessage(0, 0, "NSAutoreleasePool new")
  
  *objAppleScript = CocoaMessage(0, 0, "NSAppleScript new")
  
  If *objAppleScript
  
    *objScript = CocoaMessage(0, *objAppleScript, "initWithSource:$", @Script)
    If *objScript
      *objEventDescriptor = CocoaMessage(0, *objScript, "executeAndReturnError:", @*objErrorInfo)
      If *objEventDescriptor
        numItems = CocoaMessage(0, *objEventDescriptor, "numberOfItems")
        If numItems
          For i = 1 To numItems
            *objDescriptor = CocoaMessage(0, *objEventDescriptor, "descriptorAtIndex:", i)
            strVal = CocoaMessage(0, *objDescriptor, "stringValue")
            If strVal
              retVal + CocoaString(strVal)
              If i <> numItems : retVal + #LF$ : EndIf
            EndIf
          Next
        Else
          strVal = CocoaMessage(0, *objEventDescriptor, "stringValue")
          If strVal
            retVal = CocoaString(strVal)
          EndIf
        EndIf
      Else
        If *objErrorInfo
          count = CocoaMessage(0, *objErrorInfo, "count")
          Dim keyName.s(count)
          *enumerator = CocoaMessage(0, *objErrorInfo, "keyEnumerator")
          If *enumerator
            i = 1
            Repeat
              *key = CocoaMessage(0, *enumerator, "nextObject")
              If *key
                keyName(i) = CocoaString(*key)
                i + 1
              EndIf
            Until *key = 0
          EndIf
          retVal = "[ErrorInfo]" + #LF$
          For i = 1 To count
            name.s = keyName(i)
            *object = CocoaMessage(0, *objErrorInfo, "objectForKey:$", @keyName(i))
            retVal + "- " + keyName(i) + " = " + CocoaString(CocoaMessage(0, *object, "description")) + #LF$
          Next
        EndIf
      EndIf
    EndIf
  EndIf
  
  CocoaMessage(0, *objPool, "release")
  
  ProcedureReturn retVal 
EndProcedure

CompilerIf #PB_Compiler_IsMainFile
  
  Define script.s, result.s
  
  ;script = "tell application " + Chr(34) + "Finder" + Chr(34) + " To get the name of every item in the desktop"
  ;script = ~"tell app \"Finder\" \n beep \n delay 1 \n beep \n end tell"
  script = ~"tellx app \"Finder\" \n beep \n delay 1 \n beep \n end tell" ; Error
  result = AppleScript(script)
  If Left(result, 11) = "[ErrorInfo]"
    Debug result
  Else
    Debug result
  EndIf
  
CompilerEndIf
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
Shardik
Addict
Addict
Posts: 1991
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: [PB Cocoa] Methods, Tips & Tricks

Post by Shardik »

Bmld756 wrote: Sun Apr 23, 2023 8:56 pm Hello,

I found 'Sorting data by clicking a column header ' but the code don't work correctly. The text in the cell disappear, It is certainly too old.
You are right. My example Sorting data by clicking a column header was posted by me in April 2013 and doesn't work anymore with PB 6.0+. Beginning with PB 6.0 Fred implemented the new PBIconTextCell which enables the display of both an icon and text in a single cell. But therefore unfortunately the old modifications don't work anymore in PB 6.0+. Therefore I had already posted this update of my example which works in PB 5.73 and older and in PB 6.0+. My example has the advantage over your example to also display a sort indicator icon at the right side of the header cell in the sorted column. And it is possible to change between ascending and descending sort order by successive clicks on a header cell.
User avatar
tikidays
User
User
Posts: 43
Joined: Tue Oct 24, 2023 6:47 am
Location: New Zealand
Contact:

Re: [PB Cocoa] Methods, Tips & Tricks

Post by tikidays »

Is it possible to get this work under 14.x.x?

wilbert wrote: Tue Oct 02, 2012 8:22 am Recolor a button gadget using a Core Image Filter

Code: Select all

If OpenWindow(0, 0, 0, 220, 200, "CIFilter example", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  
  ButtonGadget(0, 10, 10, 200, 30, "Button")
  
  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:$", @"1.0 0.7 0.3 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
  
  Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
  
EndIf
Post Reply