From bf11da047edc1c6aec27a490f74553f2b9cea94e Mon Sep 17 00:00:00 2001 From: sekelsenmat Date: Mon, 10 Mar 2008 11:51:50 +0000 Subject: [PATCH] Improves the status item example. git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@374 8e941d3f-bd1b-0410-a28a-d453659cc2b4 --- .../pascocoa/examples/statusitem/actions.pas | 82 +++++++++++--- .../examples/statusitem/createbundle.sh | 56 ++++++++++ .../examples/statusitem/statusitem.lpi | 104 +++++------------- .../examples/statusitem/statusitem.pas | 29 ++--- bindings/pascocoa/foundation/NSObject.inc | 15 +++ 5 files changed, 176 insertions(+), 110 deletions(-) create mode 100755 bindings/pascocoa/examples/statusitem/createbundle.sh diff --git a/bindings/pascocoa/examples/statusitem/actions.pas b/bindings/pascocoa/examples/statusitem/actions.pas index 804c13ab8..86dfb023d 100644 --- a/bindings/pascocoa/examples/statusitem/actions.pas +++ b/bindings/pascocoa/examples/statusitem/actions.pas @@ -31,30 +31,32 @@ type { Objective-c Methods } procedure doShowStatusitem(param1: objc.id; param2: SEL; param3: objc.id); cdecl; +procedure doHideStatusitem(param1: objc.id; param2: SEL; param3: objc.id); cdecl; var actionList: TMyActionList; +{ Other helper functions } +function GetResourcesDir: string; +function CreateButton(AView: NSView; ATitle: shortstring; + AX, AY, AWidth, AHeight: Double; + ACallbackName: string; ACallbackClass: NSObject): NSButton; + implementation { TMyActionList } +{ Adds methods to the class } procedure TMyActionList.AddMethods; -var - method_list: Pobjc_method_list; begin - { Adds methods to the class } - - method_list := GetMem(SizeOf(objc_method_list)); { We can't free this until the last instance is freed } - - method_list^.method_count := 1; - method_list^.method_list[0].method_name := sel_registerName('doShowStatusitem:'); - { The first parameter is the result (v = void), + { Parameters string: + + The first parameter is the result (v = void), followed by self and _cmd (@ = id and : = SEL), and on the end "sender" (@ = id) } - method_list^.method_list[0].method_types := 'v@:@'; - method_list^.method_list[0].method_imp := IMP(@doShowStatusitem); - class_addMethods(ClassId, method_list); + + AddMethod('doShowStatusitem:', 'v@:@', @doShowStatusitem); + AddMethod('doHideStatusitem:', 'v@:@', @doHideStatusitem); end; constructor TMyActionList.Create; @@ -68,7 +70,7 @@ begin bar := NSStatusBar.systemStatusBar(); fileName := CFStringCreateWithPascalString(nil, - ExtractFilePath(ParamStr(0)) + 'icon.ico', kCFStringEncodingUTF8); + GetResourcesDir + 'icon.ico', kCFStringEncodingUTF8); image := NSImage.initWithContentsOfFile(fileName); end; @@ -76,14 +78,60 @@ end; procedure doShowStatusitem(param1: objc.id; param2: SEL; param3: objc.id); cdecl; begin + if actionList.item <> nil then Exit; + actionList.item := actionList.bar.statusItemWithLength(NSSquareStatusItemLength); - - if actionList.item = nil then WriteLn('The item is nil!'); - if actionList.image = nil then WriteLn('The image is nil!'); - actionList.item.retain(); actionList.item.setImage(actionList.image); end; +procedure doHideStatusitem(param1: objc.id; param2: SEL; param3: objc.id); cdecl; +begin + if actionList.item = nil then Exit; + + actionList.item.Free; + actionList.item := nil; +end; + +{ Other helper functions } + +function GetResourcesDir: string; +const + BundleResourcesDirectory = '/Contents/Resources/'; +var + pathRef: CFURLRef; + pathCFStr: CFStringRef; + pathStr: shortstring; +begin + // Under Mac OS X we need to get the location of the bundle + pathRef := CFBundleCopyBundleURL(CFBundleGetMainBundle()); + pathCFStr := CFURLCopyFileSystemPath(pathRef, kCFURLPOSIXPathStyle); + CFStringGetPascalString(pathCFStr, @pathStr, 255, CFStringGetSystemEncoding()); + CFRelease(pathRef); + CFRelease(pathCFStr); + + Result := pathStr + BundleResourcesDirectory; +end; + +function CreateButton(AView: NSView; ATitle: shortstring; + AX, AY, AWidth, AHeight: Double; + ACallbackName: string; ACallbackClass: NSObject): NSButton; +var + CFButtonText: CFStringRef; + ButtonRect: NSRect; +begin + CFButtonText := CFStringCreateWithPascalString(nil, ATitle, kCFStringEncodingUTF8); + ButtonRect.origin.x := AX; + ButtonRect.origin.y := AY; + ButtonRect.size.width := AWidth; + ButtonRect.size.height := AHeight; + Result := NSButton.initWithFrame(ButtonRect); + Result.setTitle(CFButtonText); + Result.setBezelStyle(NSRoundedBezelStyle); + Result.setAction(sel_registerName(PChar(ACallbackName))); + Result.setTarget(ACallbackClass.Handle); + AView.addSubview(Result); +end; + end. diff --git a/bindings/pascocoa/examples/statusitem/createbundle.sh b/bindings/pascocoa/examples/statusitem/createbundle.sh new file mode 100755 index 000000000..c2485e123 --- /dev/null +++ b/bindings/pascocoa/examples/statusitem/createbundle.sh @@ -0,0 +1,56 @@ +#!/bin/sh +# Force Bourne shell in case tcsh is default. +# +appname=StatusItem +appfolder=$appname.app +macosfolder=$appfolder/Contents/MacOS +plistfile=$appfolder/Contents/Info.plist +appfile=statusitem +# +if ! [ -e $appfile ] +then + echo "$appfile does not exist" +elif [ -e $appfolder ] +then + echo "$appfolder already exists" +else + echo "Creating $appfolder..." + mkdir $appfolder + mkdir $appfolder/Contents + mkdir $appfolder/Contents/MacOS + mkdir $appfolder/Contents/Resources +# +# Instead of copying executable into .app folder after each compile, +# simply create a symbolic link to executable. + ln -s ../../../$appname $macosfolder/$appname +# Copy the resource files to the correct place + cp icon.ico $appfolder/Contents/Resources +# +# Create PkgInfo file. + echo "APPLMAG#" >$appfolder/Contents/PkgInfo +# +# Create information property list file (Info.plist). + echo '' >$plistfile + echo '' >>$plistfile + echo '' >>$plistfile + echo '' >>$plistfile + echo ' CFBundleDevelopmentRegion' >>$plistfile + echo ' English' >>$plistfile + echo ' CFBundleExecutable' >>$plistfile + echo ' '$appname'' >>$plistfile + echo ' CFBundleIconFile' >>$plistfile + echo ' macicon.icns' >>$plistfile + echo ' CFBundleIdentifier' >>$plistfile + echo ' org.turbocircuit.turbocircuit' >>$plistfile + echo ' CFBundleInfoDictionaryVersion' >>$plistfile + echo ' 6.0' >>$plistfile + echo ' CFBundlePackageType' >>$plistfile + echo ' APPL' >>$plistfile + echo ' CFBundleSignature' >>$plistfile + echo ' MAG#' >>$plistfile + echo ' CFBundleVersion' >>$plistfile + echo ' 1.0' >>$plistfile + echo '' >>$plistfile + echo '' >>$plistfile +fi + diff --git a/bindings/pascocoa/examples/statusitem/statusitem.lpi b/bindings/pascocoa/examples/statusitem/statusitem.lpi index 9639d0a9c..c711d662f 100644 --- a/bindings/pascocoa/examples/statusitem/statusitem.lpi +++ b/bindings/pascocoa/examples/statusitem/statusitem.lpi @@ -7,7 +7,7 @@ - + @@ -31,10 +31,10 @@ - - + + - + @@ -60,7 +60,7 @@ - + @@ -68,15 +68,15 @@ - + - - + + @@ -162,8 +162,8 @@ - - + + @@ -171,7 +171,7 @@ - + @@ -220,18 +220,18 @@ - - + + - + - - + + @@ -248,18 +248,20 @@ - - + + + + - - + + - + @@ -271,77 +273,27 @@ - - - + - - + + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + diff --git a/bindings/pascocoa/examples/statusitem/statusitem.pas b/bindings/pascocoa/examples/statusitem/statusitem.pas index f597f54b7..fbbd636fd 100644 --- a/bindings/pascocoa/examples/statusitem/statusitem.pas +++ b/bindings/pascocoa/examples/statusitem/statusitem.pas @@ -21,16 +21,15 @@ uses const Str_Window_Title = 'StatusItem example project'; Str_Show_Button = 'Show StatusItem'; + Str_Hide_Button = 'Hide StatusItem'; var { classes } pool: NSAutoreleasePool; MainWindow: NSWindow; MainWindowView: NSView; - MyButton: NSButton; - { strings } - CFTitle, CFButtonText: CFStringRef; - { sizes } - MainWindowRect, ButtonRect: NSRect; + { strings and sizes} + CFTitle: CFStringRef; + MainWindowRect: NSRect; begin { Creates the AutoreleasePool } pool := NSAutoreleasePool.Create; @@ -57,19 +56,15 @@ begin actionList := TMyActionList.Create(); - { Puts some buttons on the window } + { Adds the buttons } - CFButtonText := CFStringCreateWithPascalString(nil, Str_Show_Button, kCFStringEncodingUTF8); - ButtonRect.origin.x := 50.0; - ButtonRect.origin.y := MainWindowRect.size.height - 50.0; - ButtonRect.size.width := 100.0; - ButtonRect.size.height := 25.0; - MyButton := NSButton.initWithFrame(ButtonRect); - MyButton.setStringValue(CFButtonText); - MyButton.setBezelStyle(NSRoundedBezelStyle); - MyButton.setAction(sel_registerName('doShowStatusitem:')); - MyButton.setTarget(actionList.Handle); - MainWindowView.addSubview(MyButton); + CreateButton(MainWindowView, Str_Show_Button, + 50.0, MainWindowRect.size.height - 50.0, 200.0, 25.0, + 'doShowStatusitem:', actionList); + + CreateButton(MainWindowView, Str_Hide_Button, + 50.0, MainWindowRect.size.height - 100.0, 200.0, 25.0, + 'doHideStatusitem:', actionList); { Enters main message loop } diff --git a/bindings/pascocoa/foundation/NSObject.inc b/bindings/pascocoa/foundation/NSObject.inc index 21aa833e3..7369ef9d3 100644 --- a/bindings/pascocoa/foundation/NSObject.inc +++ b/bindings/pascocoa/foundation/NSObject.inc @@ -59,6 +59,8 @@ FOUNDATION_EXPORT unsigned NSExtraRefCount(id object);} destructor Destroy; override; { Extra binding functions } function getClass: objc.id; virtual; + { Class creation methods } + procedure AddMethod(aName, aParameters: string; aPointer: Pointer); public {+ (void)load; @@ -191,6 +193,19 @@ begin Result := objc_getClass(Str_NSObject); end; +procedure NSObject.AddMethod(aName, aParameters: string; aPointer: Pointer); +var + method_list: Pobjc_method_list; +begin + method_list := GetMem(SizeOf(objc_method_list)); { We can't free this until the last instance is freed } + + method_list^.method_count := 1; + method_list^.method_list[0].method_name := sel_registerName(PChar(aName)); + method_list^.method_list[0].method_types := PChar(aParameters); + method_list^.method_list[0].method_imp := IMP(aPointer); + class_addMethods(ClassId, method_list); +end; + {*************** Basic protocols ***************} function NSObject.retain: objc.id;