Improves the status item example.

git-svn-id: https://svn.code.sf.net/p/lazarus-ccr/svn@374 8e941d3f-bd1b-0410-a28a-d453659cc2b4
This commit is contained in:
sekelsenmat 2008-03-10 11:51:50 +00:00
parent 6308ce38ab
commit bf11da047e
5 changed files with 176 additions and 110 deletions

View File

@ -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.

View File

@ -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 '<?xml version="1.0" encoding="UTF-8"?>' >$plistfile
echo '<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">' >>$plistfile
echo '<plist version="1.0">' >>$plistfile
echo '<dict>' >>$plistfile
echo ' <key>CFBundleDevelopmentRegion</key>' >>$plistfile
echo ' <string>English</string>' >>$plistfile
echo ' <key>CFBundleExecutable</key>' >>$plistfile
echo ' <string>'$appname'</string>' >>$plistfile
echo ' <key>CFBundleIconFile</key>' >>$plistfile
echo ' <string>macicon.icns</string>' >>$plistfile
echo ' <key>CFBundleIdentifier</key>' >>$plistfile
echo ' <string>org.turbocircuit.turbocircuit</string>' >>$plistfile
echo ' <key>CFBundleInfoDictionaryVersion</key>' >>$plistfile
echo ' <string>6.0</string>' >>$plistfile
echo ' <key>CFBundlePackageType</key>' >>$plistfile
echo ' <string>APPL</string>' >>$plistfile
echo ' <key>CFBundleSignature</key>' >>$plistfile
echo ' <string>MAG#</string>' >>$plistfile
echo ' <key>CFBundleVersion</key>' >>$plistfile
echo ' <string>1.0</string>' >>$plistfile
echo '</dict>' >>$plistfile
echo '</plist>' >>$plistfile
fi

View File

@ -7,7 +7,7 @@
<MainUnit Value="0"/>
<IconPath Value="./"/>
<TargetFileExt Value=""/>
<ActiveEditorIndexAtStart Value="5"/>
<ActiveEditorIndexAtStart Value="1"/>
</General>
<VersionInfo>
<ProjectVersion Value=""/>
@ -31,10 +31,10 @@
<Filename Value="statusitem.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="statusitem"/>
<CursorPos X="104" Y="43"/>
<TopLine Value="20"/>
<CursorPos X="1" Y="34"/>
<TopLine Value="32"/>
<EditorIndex Value="0"/>
<UsageCount Value="39"/>
<UsageCount Value="41"/>
<Loaded Value="True"/>
</Unit0>
<Unit1>
@ -60,7 +60,7 @@
<Filename Value="../../appkit/NSAlert.inc"/>
<CursorPos X="1" Y="12"/>
<TopLine Value="1"/>
<UsageCount Value="21"/>
<UsageCount Value="22"/>
<Loaded Value="True"/>
</Unit4>
<Unit5>
@ -68,15 +68,15 @@
<CursorPos X="12" Y="123"/>
<TopLine Value="37"/>
<EditorIndex Value="2"/>
<UsageCount Value="14"/>
<UsageCount Value="15"/>
<Loaded Value="True"/>
</Unit5>
<Unit6>
<Filename Value="../../appkit/AppKit.inc"/>
<CursorPos X="23" Y="56"/>
<TopLine Value="44"/>
<EditorIndex Value="8"/>
<UsageCount Value="12"/>
<EditorIndex Value="9"/>
<UsageCount Value="13"/>
<Loaded Value="True"/>
</Unit6>
<Unit7>
@ -162,8 +162,8 @@
<UnitName Value="appkit"/>
<CursorPos X="13" Y="21"/>
<TopLine Value="15"/>
<EditorIndex Value="7"/>
<UsageCount Value="20"/>
<EditorIndex Value="8"/>
<UsageCount Value="21"/>
<Loaded Value="True"/>
</Unit19>
<Unit20>
@ -171,7 +171,7 @@
<CursorPos X="1" Y="97"/>
<TopLine Value="92"/>
<EditorIndex Value="4"/>
<UsageCount Value="16"/>
<UsageCount Value="17"/>
<Loaded Value="True"/>
</Unit20>
<Unit21>
@ -220,18 +220,18 @@
</Unit27>
<Unit28>
<Filename Value="../../foundation/NSObject.inc"/>
<CursorPos X="1" Y="25"/>
<TopLine Value="9"/>
<CursorPos X="5" Y="206"/>
<TopLine Value="192"/>
<EditorIndex Value="5"/>
<UsageCount Value="12"/>
<UsageCount Value="13"/>
<Loaded Value="True"/>
</Unit28>
<Unit29>
<Filename Value="../../appkit/NSStatusBar.inc"/>
<CursorPos X="10" Y="61"/>
<TopLine Value="36"/>
<EditorIndex Value="9"/>
<UsageCount Value="16"/>
<EditorIndex Value="10"/>
<UsageCount Value="17"/>
<Loaded Value="True"/>
</Unit29>
<Unit30>
@ -248,18 +248,20 @@
</Unit31>
<Unit32>
<Filename Value="../../../objc/objc.inc"/>
<CursorPos X="50" Y="52"/>
<TopLine Value="49"/>
<CursorPos X="10" Y="82"/>
<TopLine Value="73"/>
<EditorIndex Value="6"/>
<UsageCount Value="12"/>
<Loaded Value="True"/>
</Unit32>
<Unit33>
<Filename Value="actions.pas"/>
<IsPartOfProject Value="True"/>
<UnitName Value="actions"/>
<CursorPos X="16" Y="84"/>
<TopLine Value="69"/>
<CursorPos X="13" Y="131"/>
<TopLine Value="118"/>
<EditorIndex Value="1"/>
<UsageCount Value="23"/>
<UsageCount Value="25"/>
<Loaded Value="True"/>
</Unit33>
<Unit34>
@ -271,77 +273,27 @@
</Unit34>
<Unit35>
<Filename Value="../../appkit/NSImage.inc"/>
<IsPartOfProject Value="True"/>
<UnitName Value="Unit1"/>
<CursorPos X="16" Y="15"/>
<TopLine Value="59"/>
<EditorIndex Value="3"/>
<UsageCount Value="22"/>
<UsageCount Value="24"/>
<Loaded Value="True"/>
</Unit35>
<Unit36>
<Filename Value="/System/Library/Frameworks/Foundation.framework/Headers/NSObject.h"/>
<CursorPos X="14" Y="35"/>
<TopLine Value="113"/>
<EditorIndex Value="6"/>
<UsageCount Value="10"/>
<EditorIndex Value="7"/>
<UsageCount Value="11"/>
<Loaded Value="True"/>
<SyntaxHighlighter Value="C++"/>
</Unit36>
</Units>
<JumpHistory Count="13" HistoryIndex="12">
<JumpHistory Count="1" HistoryIndex="0">
<Position1>
<Filename Value="../../appkit/appkit.pas"/>
<Caret Line="21" Column="13" TopLine="15"/>
</Position1>
<Position2>
<Filename Value="../../appkit/NSImage.inc"/>
<Caret Line="3" Column="1" TopLine="1"/>
</Position2>
<Position3>
<Filename Value="../../appkit/NSImage.inc"/>
<Caret Line="39" Column="3" TopLine="30"/>
</Position3>
<Position4>
<Filename Value="../../appkit/NSImage.inc"/>
<Caret Line="170" Column="16" TopLine="51"/>
</Position4>
<Position5>
<Filename Value="../../appkit/NSImage.inc"/>
<Caret Line="51" Column="17" TopLine="47"/>
</Position5>
<Position6>
<Filename Value="actions.pas"/>
<Caret Line="63" Column="25" TopLine="58"/>
</Position6>
<Position7>
<Filename Value="actions.pas"/>
<Caret Line="70" Column="17" TopLine="65"/>
</Position7>
<Position8>
<Filename Value="actions.pas"/>
<Caret Line="33" Column="28" TopLine="24"/>
</Position8>
<Position9>
<Filename Value="actions.pas"/>
<Caret Line="79" Column="49" TopLine="69"/>
</Position9>
<Position10>
<Filename Value="../../appkit/NSStatusBar.inc"/>
<Caret Line="75" Column="32" TopLine="58"/>
</Position10>
<Position11>
<Filename Value="actions.pas"/>
<Caret Line="79" Column="39" TopLine="70"/>
</Position11>
<Position12>
<Filename Value="/System/Library/Frameworks/Foundation.framework/Headers/NSObject.h"/>
<Caret Line="1" Column="1" TopLine="1"/>
</Position12>
<Position13>
<Filename Value="../../foundation/NSObject.inc"/>
<Caret Line="9" Column="22" TopLine="1"/>
</Position13>
</Position1>
</JumpHistory>
</ProjectOptions>
<CompilerOptions>

View File

@ -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 }

View File

@ -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;