[LCB FFI] Why can't I bind to these or make this Aggregate Type?

LiveCode Builder is a language for extending LiveCode's capabilities, creating new object types as Widgets, and libraries that access lower-level APIs in OSes, applications, and DLLs.

Moderators: LCMark, LCfraser

Post Reply
PaulDaMacMan
Posts: 324
Joined: Wed Apr 24, 2013 4:53 pm
Contact:

[LCB FFI] Why can't I bind to these or make this Aggregate Type?

Post by PaulDaMacMan » Thu Oct 29, 2020 3:01 am

Anybody know how to make NSRect or CGRect struct in LCB?
Or know the proper way to bind to any of Apple's Foundation functions that return one (such as NSMakeRect, CGRectMake, or NSRectFromString)?
I've tried a bunch of different binding strings such as:
"c:CoreFoundation.framework>CGRectMake","c:CoreGraphics.framework>CGRectMake" etc. no joy.

I see CGRectMake is used in various places in LC's source in conjunction with MCRectangleToCGRect and MCGRectangleFromCGRect
It would be good if I could bind "<builtin>" to MCRectangleToCGRect and MCGRectangleFromCGRect, but I can't bind to those either.
Maybe they functions could be exposed in LCB and added to the LCB objc module? (although technically they're C structs not ObjcObjects).

I've also tried to make the Foreign aggregate type info for the struct "qqqq" (4x NaturalFloat) that fails with no error object (or some similar message like that).

--------------------------------------------------------------------------------------------------------------
As a side note, I found you can use the LCB rectangle type in a non-widget library simply by adding:

Code: Select all

use com.livecode.canvas
without that line you would get the error message in the builder "syntax is not allowed for this module type" if you tried to do something like

Code: Select all

put rectangle [0,0,300,500] into tRect
in an LCB Library (not a Widget)
-------------------------------------------------------------------------------------------------------------

Lastly, I've been wondering if there's a roadmap for LiveCode Builder? Is there any new syntax or other improvements coming to the language at some point? Or at least a plan to do that in the future? I think you all know that I think LCB is the greatest thing since sliced bread (or at least since CompileIt!), but it's also very frustrating and limiting at times.
My LCB Repos: https://github.com/PaulMcClernan/

trevordevore
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 993
Joined: Sat Apr 08, 2006 3:06 pm
Location: Overland Park, Kansas
Contact:

Re: [LCB FFI] Why can't I bind to these or make this Aggregate Type?

Post by trevordevore » Thu Oct 29, 2020 4:06 am

Here is what I found in some code from some WebKit example code at https://github.com/trevordevore/lc-maco ... webkit.lcb:

Code: Select all

public foreign type NSRect binds to "MCAggregateTypeInfo:qqqq"
private foreign handler ObjC_WebViewInitWithFrame (in pWebView as ObjcId, in pRect as NSRect) \
        returns ObjcId \
        binds to "objc:WebView.-initWithFrame:"
 
Then in a public handler I use this:

Code: Select all

variable tNSRect as NSRect
put [0, 0, 200, 200] into tNSRect
put ObjC_WebViewInitWithFrame(tWebView, tNSRect) into tWebView
Trevor DeVore
ScreenSteps - https://www.screensteps.com

LiveCode Repos - https://github.com/search?q=user%3Atrevordevore+topic:livecode
LiveCode Builder Repos - https://github.com/search?q=user%3Atrevordevore+topic:livecode-builder

PaulDaMacMan
Posts: 324
Joined: Wed Apr 24, 2013 4:53 pm
Contact:

Re: [LCB FFI] Why can't I bind to these or make this Aggregate Type?

Post by PaulDaMacMan » Fri Oct 30, 2020 1:20 am

trevordevore wrote:
Thu Oct 29, 2020 4:06 am
Here is what I found in some code from some WebKit example code at https://github.com/trevordevore/lc-maco ... webkit.lcb:

Code: Select all

public foreign type NSRect binds to "MCAggregateTypeInfo:qqqq"
private foreign handler ObjC_WebViewInitWithFrame (in pWebView as ObjcId, in pRect as NSRect) \
        returns ObjcId \
        binds to "objc:WebView.-initWithFrame:"
 
Then in a public handler I use this:

Code: Select all

variable tNSRect as NSRect
put [0, 0, 200, 200] into tNSRect
put ObjC_WebViewInitWithFrame(tWebView, tNSRect) into tWebView
Thanks again Trevor! I was still not able to get those C CF Foundation CG binding strings to work for some reason, but your confirming that the NSRect ForeignType declaration (which is actually used as an example of foreign type in the LCB guide) should work as expected was enough to keep me going in that direction. I was able to get my initial goal working, which was to programmatically create / display an NSWindow.

Here's the code in case anyone is interested:

Code: Select all

public foreign type NSRect binds to "MCAggregateTypeInfo:qqqq"

private foreign handler objC_NSObjectClassName(in pNSObj as ObjcId) returns ObjcId binds to "objc:NSObject.className"
private foreign handler ObjC_NSWindowAlloc() returns ObjcRetainedId binds to "objc:NSWindow.+alloc"
private foreign handler ObjC_NSWindowInitWithRectStyleBackingDefer(in pObj as ObjcId, in pRect as NSRect, in pStyleMask as CLong, in pBackingStoreType as CLong, in pDefer as CBool) returns ObjcId binds to "objc:NSWindow.-initWithContentRect:styleMask:backing:defer:"
private foreign handler ObjC_NSWindowControllerAlloc() returns ObjcRetainedId binds to "objc:NSWindowController.+alloc"
private foreign handler ObjC_NSWindowControllerInitWithWindow(in pObj as ObjcId,in pNSWindow as ObjcId) returns ObjcId binds to "objc:NSWindowController.-initWithWindow:"
private foreign handler ObjC_NSWindowControllerShowWindow(in pObj as ObjcId,in pNSWindow as ObjcId) returns nothing binds to "objc:NSWindowController.-showWindow:"
private foreign handler ObjC_NSWindowSetTitle(in pObj as ObjcId, in pTitleNSStr as ObjcId) returns ObjcId binds to "objc:NSWindow.-setTitle:"

public variable sMyWindow as ObjcObject
public variable sMyWindowController as ObjcObject

public handler CreateNSWindow(in pWindowH as optional Number,in pWindowW as optional Number) returns optional any
   variable tNSSharedApplication as ObjcId
   variable tNSRect as NSRect
   variable tWindow as optional ObjcObject
   variable tStyleMask as CLong
   variable tNSObj as ObjcId
   variable tStr as String
   -- if pWindowH is nothing then
   -- put 200 into pWindowH
   --end if
   --if pWindowW is nothing then
   --   put 200 into pWindowW
   --end if
   -- put 4096 into tStyleMask -- <- no title bar style
   put 1 shifted left by 0 bitwise into tStyleMask
   unsafe
      put [200,200,500,500] into tNSRect
      put ObjC_NSWindowAlloc() into sMyWindow
      put ObjC_NSWindowInitWithRectStyleBackingDefer(sMyWindow,tNSRect,tStyleMask,2,true) into sMyWindow
     -- log sMyWindow
     ----------------- just used as a check --------------------
     -- put objC_NSObjectClassName(sMyWindow) into tNSObj 
     -- put StringFromNSString(tNSObj) into tStr 
      -- log tStr
      --------------------------------------------------------------
      ObjC_NSWindowSetTitle(sMyWindow,StringToNSString("Paul's NSWindow Test"))
      put ObjC_NSWindowControllerAlloc() into sMyWindowController
      put ObjC_NSWindowControllerInitWithWindow(sMyWindowController,sMyWindow) into sMyWindowController
      ObjC_NSWindowControllerShowWindow(sMyWindowController,sMyWindow)
    end unsafe
end handler
Last edited by PaulDaMacMan on Fri Oct 30, 2020 2:31 am, edited 1 time in total.
My LCB Repos: https://github.com/PaulMcClernan/

PaulDaMacMan
Posts: 324
Joined: Wed Apr 24, 2013 4:53 pm
Contact:

Re: [LCB FFI] Why can't I bind to these or make this Aggregate Type?

Post by PaulDaMacMan » Fri Oct 30, 2020 2:02 am

In fact it seems part of the problem was just having this binding string in my lcb file, even if it's not called from any handler, causes a crash when I go to compile with extension builder. Which seems like it might be a bug. Perhaps it's caused by the fact that the LC engine itself already uses CGRectMake?

This is the offending binding string:

Code: Select all

 private foreign handler c_CGRectMake(in pX as NaturalFloat,in pY as NaturalFloat, in pW as NaturalFloat, in pH as NaturalFloat ) returns NSRect binds to "c:CoreFoundation.framework>CGRectMake" 
My LCB Repos: https://github.com/PaulMcClernan/

trevordevore
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 993
Joined: Sat Apr 08, 2006 3:06 pm
Location: Overland Park, Kansas
Contact:

Re: [LCB FFI] Why can't I bind to these or make this Aggregate Type?

Post by trevordevore » Fri Oct 30, 2020 2:16 am

You’re welcome Paul. I’m glad you got the window code working.
Trevor DeVore
ScreenSteps - https://www.screensteps.com

LiveCode Repos - https://github.com/search?q=user%3Atrevordevore+topic:livecode
LiveCode Builder Repos - https://github.com/search?q=user%3Atrevordevore+topic:livecode-builder

PaulDaMacMan
Posts: 324
Joined: Wed Apr 24, 2013 4:53 pm
Contact:

Re: [LCB FFI] Why can't I bind to these or make this Aggregate Type?

Post by PaulDaMacMan » Fri Oct 30, 2020 7:35 pm

For future reference...
Here's a list of already-bit-shifted numbers for adding together to create NSWindow's styleMask value for the type of window you want to create:
-- Borderless = 0
-- Titled = 1
-- Closable = 2
-- Miniaturizable = 4
-- Resizable = 8
-- Utility = 16
-- DocModal = 64
-- NonactivatingPanel = 128
-- TexturedBackground = 256
-- Unscaled = 2048
-- UnifiedTitleAndToolbar = 4096
-- Hud = 8192
-- FullScreenWindow = 16384
-- FullSizeContentView = 32768
My LCB Repos: https://github.com/PaulMcClernan/

Post Reply

Return to “LiveCode Builder”