Lazarus

Programming => Widgetset => Cocoa => Topic started by: dbannon on September 28, 2020, 05:20:37 am

Title: MacOS object / class structure
Post by: dbannon on September 28, 2020, 05:20:37 am
Hi Folks, hoping someone who understands this better than me can point me in right direction.

While chasing a bug in RichMemo on Mac, that is, why GetTextLen does not work, I realised it also does not work for TMemo.  So, following the code I determined that the issue is in
lcl/interfaces/cocoa/cocoaWSCommon # 1762 TCocoaWSWinControl.GetTextLen(),

Code: Pascal  [Select][+][-]
  1. obj: NSObject;
  2. ...
  3. obj := NSObject(AWinControl.Handle);
  4. Result := obj.isKindOfClass_(NSControl);     // returns false

Decides that the passed handle is not a NSControl and exits. Neither TRichMemo nor TMemo are NSControls and GetTextLen does not work.  Thats does not surprise me. But I found that TEdit and TLabel work fine, they are NSControls. Surprise.

So, my question, how does a component, descended from TComponent, get to be a NSControl in Apple speak ?

NSControl, NSObject and obj.isKindOfClass_() are imported from Apple Object C headers.

And pointers gratefully received.

Davo

Title: Re: MacOS object / class structure
Post by: skalogryz on September 28, 2020, 06:27:47 am
Cocoa "controls" are composite in nature. Where in WinAPI you'd have a single control for RICHEDIT or EDIT (Memo), in Cocoa these are two separate controls: NSTextViewand NSScrollView. (with NSTextView embedded into NSScrollView). NSTextViewby itself doesn't have any scrolling functionality (unlike RICHEDIT/EDIT in WinAPI), all scrolling is done by NSScrollView.

Thus mapping LCL TControl.Handle to something Cocoa, you need to be careful.

The returned handles are explained in this article (https://wiki.freepascal.org/Cocoa_Internals/Widgetset#Handles_Reference).
For TMemo (and TRichMemo) the handle returned is NSScrollView.
In order to reach NSTextView, you need to do an extra step, like that:
Code: Pascal  [Select][+][-]
  1. doc := NSTextView(NSScrollView(Memo1.Handle).documentView);

Aside note. NSControl is used only for a small amount of controls. Buttons, Single scrollbars, Trackbar, Progress bar and Single-line read-only edit. (The actual editing capabilities of Cocoa's TEdit is implemented via NSTextView and a special  fieldEditor mechanism)

While working with LCL one might get accustomed to "everything is Control". In Cocoa "control" is used for a very few UI elements. On the other hand, one may assume that "everything is NSView" in Cocoa :)
Title: Re: MacOS object / class structure
Post by: dbannon on September 28, 2020, 08:31:01 am
Wow, a very comprehensive answer Skalogryz !

I thank you very much, I will work through what you say there, thanks !

Davo
TinyPortal © 2005-2018