Commits

Armin Rigo committed 5ce3f01

Add the Cocoa demo by Juraj Sukop.

Comments (0)

Files changed (1)

demo/cffi-cocoa.py

+# Based on http://cocoawithlove.com/2010/09/minimalist-cocoa-programming.html
+# by Juraj Sukop
+
+from cffi import FFI
+
+ffi = FFI()
+ffi.cdef('''
+    
+    typedef signed char BOOL;
+    
+    typedef long NSInteger;
+    typedef unsigned long NSUInteger;
+    typedef NSInteger NSApplicationActivationPolicy;
+    typedef NSUInteger NSBackingStoreType;
+    typedef NSUInteger NSStringEncoding;
+    
+    typedef double CGFloat;
+    struct CGPoint {
+        CGFloat x;
+        CGFloat y;
+    };
+    typedef struct CGPoint CGPoint;
+    struct CGSize {
+        CGFloat width;
+        CGFloat height;
+    };
+    typedef struct CGSize CGSize;
+    struct CGRect {
+        CGPoint origin;
+        CGSize size;
+    };
+    typedef struct CGRect CGRect;
+    
+    typedef CGPoint NSPoint;
+    typedef CGSize NSSize;
+    typedef CGRect NSRect;
+    
+    typedef struct objc_class *Class;
+    typedef struct objc_object {
+        Class isa;
+    } *id;
+    typedef struct objc_selector *SEL;
+
+    SEL sel_registerName(const char *str);
+    id objc_getClass(const char *name);
+    id objc_msgSend(id theReceiver, SEL theSelector, ...);
+    
+''')
+
+objc = ffi.dlopen('objc')
+appkit = ffi.dlopen('AppKit')
+
+nil = ffi.NULL
+YES = ffi.cast('BOOL', 1)
+NO = ffi.cast('BOOL', 0)
+
+NSASCIIStringEncoding = ffi.cast('NSStringEncoding', 1)
+NSApplicationActivationPolicyRegular = ffi.cast('NSApplicationActivationPolicy', 0)
+NSTitledWindowMask = ffi.cast('NSUInteger', 1)
+NSBackingStoreBuffered = ffi.cast('NSBackingStoreType', 2)
+
+NSMakePoint = lambda x, y: ffi.new('NSPoint', (x, y))[0]
+NSMakeRect = lambda x, y, w, h: ffi.new('NSRect', ((x, y), (w, h)))[0]
+
+get, send, sel = objc.objc_getClass, objc.objc_msgSend, objc.sel_registerName
+at = lambda s: send(
+    get('NSString'),
+    sel('stringWithCString:encoding:'),
+    ffi.new('char[]', s), NSASCIIStringEncoding)
+
+send(get('NSAutoreleasePool'), sel('new'))
+app = send(get('NSApplication'), sel('sharedApplication'))
+send(app, sel('setActivationPolicy:'), NSApplicationActivationPolicyRegular)
+
+menubar = send(send(get('NSMenu'), sel('new')), sel('autorelease'))
+appMenuItem = send(send(get('NSMenuItem'), sel('new')), sel('autorelease'))
+send(menubar, sel('addItem:'), appMenuItem)
+send(app, sel('setMainMenu:'), menubar)
+
+appMenu = send(send(get('NSMenu'), sel('new')), sel('autorelease'))
+appName = send(send(get('NSProcessInfo'), sel('processInfo')), sel('processName'))
+quitTitle = send(at('Quit '), sel('stringByAppendingString:'), appName)
+quitMenuItem = send(send(send(
+            get('NSMenuItem'), sel('alloc')),
+        sel('initWithTitle:action:keyEquivalent:'),
+        quitTitle, sel('terminate:'), at('q')),
+    sel('autorelease'))
+send(appMenu, sel('addItem:'), quitMenuItem)
+send(appMenuItem, sel('setSubmenu:'), appMenu)
+
+window = send(send(send(
+            get('NSWindow'), sel('alloc')),
+        sel('initWithContentRect:styleMask:backing:defer:'),
+        NSMakeRect(0, 0, 200, 200), NSTitledWindowMask, NSBackingStoreBuffered, NO),
+    sel('autorelease'))
+send(window, sel('cascadeTopLeftFromPoint:'), NSMakePoint(20, 20))
+send(window, sel('setTitle:'), appName)
+send(window, sel('makeKeyAndOrderFront:'), nil)
+
+send(app, sel('activateIgnoringOtherApps:'), YES)
+send(app, sel('run'))
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.