Recent

Author Topic: Lists on Cocoa  (Read 1890 times)

maxnd

  • Jr. Member
  • **
  • Posts: 65
Lists on Cocoa
« on: March 21, 2021, 07:32:23 pm »
Hi,

I'm trying to create a bullet list in a NSTextView widget with this code (Lazarus 2.0.12):
Code: Pascal  [Select][+][-]
  1. {$mode objfpc}{$H+}
  2. {$modeswitch objectivec1}
  3.  
  4. [...]
  5.  
  6. uses
  7.   Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
  8.   CocoaThemes, CocoaAll, CocoaTextEdits, CocoaUtils, LazUTF8;
  9. [...]
  10.  
  11. procedure TForm1.CreateList;
  12. var
  13.   rng: NSRange;
  14.   par: NSMutableParagraphStyle;
  15.   textLists: NSTextList;
  16. begin
  17.   textLists.initWithMarkerFormat_options(NSStringUtf8('*'), 0);
  18.   //The GetWrite Para is taken from TRichMemo Cocoa code
  19.   par := GetWritePara(TCocoaTextView(NSScrollView(dbText.Handle).
  20.     documentView).textStorage, 1);
  21.   rng.location := 0;
  22.   rng.length:= UTF8Length(dbText.Text) - 1;
  23.   par.setTextLists(NSArray(textLists));
  24.   TCocoaTextView(NSScrollView(Memo1.Handle).documentView).
  25.     textStorage.addAttribute_value_range(NSParagraphStyleAttributeName,
  26.     par, rng);
  27. end;

Anyway, the line #17 raises an error during compilation execution. initWithMarkerFormat_options seems not to work. Any idea?

Thanks :)
« Last Edit: March 21, 2021, 08:06:30 pm by maxnd »

Jonas Maebe

  • Hero Member
  • *****
  • Posts: 1058
Re: Lists on Cocoa
« Reply #1 on: March 21, 2021, 09:14:31 pm »
That's like doing this:
Code: Pascal  [Select][+][-]
  1. type
  2.   tc = class
  3.     constructor create; virtual,
  4.   end;
  5.  
  6. constructor tc.create; virtual;
  7. begin
  8. end;
  9.  
  10. var
  11.   c: tc;
  12. begin
  13.   c.create;
  14. end.
  15.  
You have not initialised textLists anywhere, yet you are sending a message to it (~ calling a virtual method of it). See https://wiki.freepascal.org/FPC_PasCocoa/Differences#No_constructors for how to construct Objective-Pascal class instances.

maxnd

  • Jr. Member
  • **
  • Posts: 65
Re: Lists on Cocoa
« Reply #2 on: March 21, 2021, 10:53:36 pm »
That's like doing this:
Code: Pascal  [Select][+][-]
  1. type
  2.   tc = class
  3.     constructor create; virtual,
  4.   end;
  5.  
  6. constructor tc.create; virtual;
  7. begin
  8. end;
  9.  
  10. var
  11.   c: tc;
  12. begin
  13.   c.create;
  14. end.
  15.  
You have not initialised textLists anywhere, yet you are sending a message to it (~ calling a virtual method of it). See https://wiki.freepascal.org/FPC_PasCocoa/Differences#No_constructors for how to construct Objective-Pascal class instances.

Thanks, now it works.

Anyway, the line #23 raises an error on execution:
Code: Pascal  [Select][+][-]
  1. par.setTextLists(NSArray(textLists));
How could I convert the NSTextLists textLists to an NSArray?

Jonas Maebe

  • Hero Member
  • *****
  • Posts: 1058
Re: Lists on Cocoa
« Reply #3 on: March 21, 2021, 11:17:14 pm »
Anyway, the line #23 raises an error on execution:
Code: Pascal  [Select][+][-]
  1. par.setTextLists(NSArray(textLists));
How could I convert the NSTextLists textLists to an NSArray?
NSTextLists and NSArray are completely unrelated classes, so it's normal that typecasting doesn't work: https://developer.apple.com/documentation/appkit/nstextlist?language=objc . Objective-C and Object Pascal are the same as far as that it concerned.

I don't know whether there is a convenience method to get an NSArray containing all elements from an NSTextList, and if not, what the best way would be to manually create one. I only work on the compiler support for Objective-Pascal, I don't do any Cocoa programming.

Edit: looking at the declaration of setTextLists, I see you actually want to create an NSArray containing a single element, with this single element being "textLists" (rather than an array representation of the contents of textLists). While Pascal and Objective-Pascal have some differences, things like typecasts are exactly the same in both. So NSArray(textLists) tries to typecast textLists into NSArray, rather than construct an NSArray with that variable as its single element.

In that case, you would use https://developer.apple.com/documentation/foundation/nsarray/1411981-arraywithobject?language=objc , so something like NSarray.arrayWithObject(textLists)

Edit 2: removed the '.alloc' in NSarray.arrayWithObject(textLists), as that's a convenience method that already does the alloc implicitly.
« Last Edit: March 22, 2021, 11:34:34 am by Jonas Maebe »

maxnd

  • Jr. Member
  • **
  • Posts: 65
Re: Lists on Cocoa
« Reply #4 on: March 22, 2021, 12:17:06 pm »
Thanks, now the procedure doesn't crash on run, but it still doesn't work.
The current version is:
Code: Pascal  [Select][+][-]
  1. procedure TForm1.bnSetListClick(Sender: TObject);
  2. var
  3.   rng: NSRange;
  4.   par: NSMutableParagraphStyle;
  5.   textLists: NSTextList;
  6.   arr: NSArray;
  7. begin
  8.   try
  9.     textLists := NSTextList.alloc;
  10.     textLists := textLists.init;
  11.     textLists.initWithMarkerFormat_options(NSStringUtf8('{decimal}'), 0);
  12.     textLists.setStartingItemNumber(1);
  13.     par := GetWritePara(TCocoaTextView(NSScrollView(dbText.Handle).
  14.       documentView).textStorage, 1);
  15.     rng.location := 0;
  16.     rng.length:= UTF8Length(dbText.Text) - 1;
  17.     arr := NSArray.arrayWithObject(textLists);
  18.     // the following line does nothing
  19.     par.setTextLists(arr);
  20.     // The following line works fine
  21.     par.setFirstLineHeadIndent(20);
  22.     TCocoaTextView(NSScrollView(dbText.Handle).documentView).
  23.       textStorage.addAttribute_value_range(NSParagraphStyleAttributeName,
  24.       par, rng);
  25.   finally
  26.     textLists.release;
  27.   end;
  28. end;
  29.  

I would like to set the text of the Memo field as numbered or bullet list, but nothing happens. Any idea?

 

TinyPortal © 2005-2018