Difference between revisions of "PasCocoa"
Sekelsenmat (talk | contribs) |
Sekelsenmat (talk | contribs) |
||
Line 8: | Line 8: | ||
<delphi> | <delphi> | ||
+ | { | ||
+ | simpleform.pas | ||
+ | |||
+ | This example shows how to use the PasCocoa bindings to create a | ||
+ | NSAutoreleasePool, initialize the application global variable, create | ||
+ | a simple window without contents and attach a close handler to it that | ||
+ | exits the application. | ||
+ | |||
+ | Compilation of this example requires the following options: | ||
+ | -k-framework -kcocoa -k-lobjc | ||
+ | |||
+ | This example project is released under public domain | ||
+ | |||
+ | AUTHORS: Felipe Monteiro de Carvalho | ||
+ | } | ||
program simplewindow; | program simplewindow; | ||
− | {$mode delphi} | + | {$ifdef fpc}{$mode delphi}{$endif} |
uses | uses | ||
Line 16: | Line 31: | ||
const | const | ||
− | + | Str_Window_Title = 'This is the title'; | |
− | + | Str_Window_Message = 'This is the message'; | |
var | var | ||
{ classes } | { classes } | ||
pool: NSAutoreleasePool; | pool: NSAutoreleasePool; | ||
MainWindow: NSWindow; | MainWindow: NSWindow; | ||
+ | MainWindowView: NSView; | ||
+ | TextField: NSTextField; | ||
{ strings } | { strings } | ||
CFTitle, CFMessage: CFStringRef; | CFTitle, CFMessage: CFStringRef; | ||
{ sizes } | { sizes } | ||
− | MainWindowRect: NSRect; | + | MainWindowRect, TextFieldRect: NSRect; |
begin | begin | ||
− | { | + | { Creates a AutoreleasePool for this thread. Every thread must have one } |
pool := NSAutoreleasePool.Create; | pool := NSAutoreleasePool.Create; | ||
− | + | { Creates the application NSApp object } | |
NSApp := NSApplication.sharedApplication; | NSApp := NSApplication.sharedApplication; | ||
− | + | { Creates a simple window } | |
MainWindowRect.origin.x := 300.0; | MainWindowRect.origin.x := 300.0; | ||
MainWindowRect.origin.y := 300.0; | MainWindowRect.origin.y := 300.0; | ||
Line 42: | Line 59: | ||
NSTitledWindowMask or NSClosableWindowMask or NSMiniaturizableWindowMask or NSResizableWindowMask, | NSTitledWindowMask or NSClosableWindowMask or NSMiniaturizableWindowMask or NSResizableWindowMask, | ||
NSBackingStoreBuffered, NO); | NSBackingStoreBuffered, NO); | ||
− | + | ||
+ | { Initializes the title of the window } | ||
+ | |||
+ | CFTitle := CFStringCreateWithPascalString(nil, Str_Window_Title, kCFStringEncodingUTF8); | ||
+ | MainWindow.setTitle(CFTitle); | ||
+ | |||
+ | { Adds a NSTextField with a string } | ||
+ | |||
+ | CFMessage := CFStringCreateWithPascalString(nil, Str_Window_Message, kCFStringEncodingUTF8); | ||
+ | TextFieldRect.origin.x := 0.0; | ||
+ | TextFieldRect.origin.y := 200.0; | ||
+ | TextFieldRect.size.width := 300.0; | ||
+ | TextFieldRect.size.height := 100.0; | ||
+ | TextField := NSTextField.initWithFrame(TextFieldRect); | ||
+ | TextField.setStringValue(CFMessage); | ||
+ | MainWindowView := NSView.CreateWithHandle(MainWindow.contentView); | ||
+ | MainWindowView.addSubview(TextField); | ||
+ | |||
+ | { Put's the window on the front z-order } | ||
+ | |||
MainWindow.orderFrontRegardless; | MainWindow.orderFrontRegardless; | ||
− | |||
− | |||
{ Enters main message loop } | { Enters main message loop } | ||
Line 51: | Line 85: | ||
NSApp.run; | NSApp.run; | ||
− | { | + | { Releases the AutoreleasePool for this thread } |
pool.Free; | pool.Free; | ||
end. | end. |
Revision as of 13:58, 2 March 2008
PasCocoa is the project to build object oriented bindings to use Cocoa in Pascal.
Objective-C to Pascal Bindings
Example
<delphi> {
simpleform.pas
This example shows how to use the PasCocoa bindings to create a NSAutoreleasePool, initialize the application global variable, create a simple window without contents and attach a close handler to it that exits the application.
Compilation of this example requires the following options: -k-framework -kcocoa -k-lobjc
This example project is released under public domain
AUTHORS: Felipe Monteiro de Carvalho
} program simplewindow;
{$ifdef fpc}{$mode delphi}{$endif}
uses
objc, ctypes, FPCMacOSAll, AppKit, Foundation;
const
Str_Window_Title = 'This is the title'; Str_Window_Message = 'This is the message';
var
{ classes } pool: NSAutoreleasePool; MainWindow: NSWindow; MainWindowView: NSView; TextField: NSTextField; { strings } CFTitle, CFMessage: CFStringRef; { sizes } MainWindowRect, TextFieldRect: NSRect;
begin
{ Creates a AutoreleasePool for this thread. Every thread must have one } pool := NSAutoreleasePool.Create;
{ Creates the application NSApp object } NSApp := NSApplication.sharedApplication;
{ Creates a simple window } MainWindowRect.origin.x := 300.0; MainWindowRect.origin.y := 300.0; MainWindowRect.size.width := 300.0; MainWindowRect.size.height := 500.0;
MainWindow := NSWindow.initWithContentRect(MainWindowRect, NSTitledWindowMask or NSClosableWindowMask or NSMiniaturizableWindowMask or NSResizableWindowMask, NSBackingStoreBuffered, NO);
{ Initializes the title of the window }
CFTitle := CFStringCreateWithPascalString(nil, Str_Window_Title, kCFStringEncodingUTF8); MainWindow.setTitle(CFTitle);
{ Adds a NSTextField with a string } CFMessage := CFStringCreateWithPascalString(nil, Str_Window_Message, kCFStringEncodingUTF8); TextFieldRect.origin.x := 0.0; TextFieldRect.origin.y := 200.0; TextFieldRect.size.width := 300.0; TextFieldRect.size.height := 100.0; TextField := NSTextField.initWithFrame(TextFieldRect); TextField.setStringValue(CFMessage); MainWindowView := NSView.CreateWithHandle(MainWindow.contentView); MainWindowView.addSubview(TextField);
{ Put's the window on the front z-order }
MainWindow.orderFrontRegardless;
{ Enters main message loop }
NSApp.run;
{ Releases the AutoreleasePool for this thread } pool.Free;
end. </delphi>
Subversion
svn co https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr/bindings/objc objc svn co https://lazarus-ccr.svn.sourceforge.net/svnroot/lazarus-ccr/bindings/pascocoa pascocoa
Implementation Details
Overview
The Cocoa headers contain several peculiarities that lead us to need a special structure for the bindings. First, several forward declarations of classes are done in a very unordently way. Pascal only accepts forward declarations of classes if they are all declared on the same type clause, and therefore a special session CLASSES is created on the include file.
The include file has a total of 3 separate sessions: HEADER, CLASSES and IMPLEMENTATION
A tipical include file should have this structure:
<delphi> {%mainunit appkit.pas} {
NSStatusBar.h Application Kit Copyright (c) 1997-2005, Apple Computer, Inc. All rights reserved.
}
{$ifdef HEADER} {$ifndef NSSTATUSBAR_PAS_H} {$define NSSTATUSBAR_PAS_H}
//insert constants, records and other interface declarations with the exception of classes
{$endif} {$endif} {$ifdef CLASSES} {$ifndef NSSTATUSBAR_PAS_H} {$define NSSTATUSBAR_PAS_H}
//declaration of classes and forward declarations of classes
{$endif} {$endif} {$ifdef IMPLEMENTATION}
//insert implementation declarations here. The order is not important on the implementation, so don't use extra ifdefs.
{$endif} </delphi>
HEADERS
Guidelines:
- Inclusion of headers in other frameworks should be removed, because the each framework is mapped to a pascal unit, and therefore all include files of a used framework are already accessible. Inclusion of headers of the same file framework should become include clauses which will used a C-styled ifdef mechanism to resolve in which order the include files will be added. This mechanism works fairly well and keeps the structure of the include files similar to the original one.
CLASSES
Guidelines:
- Should include the same include files as the HEADERS section
- All private members of classes should be removed