mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-09 22:32:43 +02:00
425 lines
12 KiB
ObjectPascal
425 lines
12 KiB
ObjectPascal
{
|
|
/***************************************************************************
|
|
CocoaInt.pas - CocoaInterface Object
|
|
----------------------------------------
|
|
|
|
Initial Revision : Mon August 6th CST 2004
|
|
|
|
|
|
***************************************************************************/
|
|
|
|
*****************************************************************************
|
|
* *
|
|
* This file is part of the Lazarus Component Library (LCL) *
|
|
* *
|
|
* See the file COPYING.modifiedLGPL.txt, included in this distribution, *
|
|
* for details about the copyright. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
|
* *
|
|
*****************************************************************************
|
|
}
|
|
|
|
unit CocoaInt;
|
|
|
|
{$mode objfpc}{$H+}
|
|
{$modeswitch objectivec1}
|
|
|
|
interface
|
|
|
|
uses
|
|
// rtl+ftl
|
|
Types, Classes, SysUtils, Math,
|
|
// carbon bindings
|
|
MacOSAll,
|
|
// interfacebase
|
|
InterfaceBase, GraphType,
|
|
// private
|
|
CocoaAll, CocoaPrivate, CocoaUtils, CocoaGDIObjects, CocoaTextLayout,
|
|
// LCL
|
|
LCLStrConsts, LMessages, LCLMessageGlue, LCLProc, LCLIntf, LCLType,
|
|
CocoaWSFactory;
|
|
|
|
type
|
|
|
|
{ TCocoaTimerObject }
|
|
|
|
TCocoaTimerObject=objcclass(NSObject)
|
|
func : TWSTimerProc;
|
|
procedure timerEvent; message 'timerEvent';
|
|
class function initWithFunc(afunc: TWSTimerProc): TCocoaTimerObject; message 'initWithFunc:';
|
|
end;
|
|
|
|
{ TCocoaAppDelegate }
|
|
|
|
TCocoaAppDelegate = objcclass(NSObject, NSApplicationDelegateProtocol)
|
|
function applicationShouldTerminate(sender: NSApplication): NSApplicationTerminateReply; message 'applicationShouldTerminate:';
|
|
end;
|
|
|
|
{ TCocoaWidgetSet }
|
|
|
|
TCocoaWidgetSet = class(TWidgetSet)
|
|
private
|
|
FTerminating: Boolean;
|
|
|
|
pool : NSAutoreleasePool;
|
|
NSApp : NSApplication;
|
|
delegate : TCocoaAppDelegate;
|
|
protected
|
|
function GetAppHandle: THandle; override;
|
|
public
|
|
constructor Create; override;
|
|
destructor Destroy; override;
|
|
|
|
function LCLPlatform: TLCLPlatform; override;
|
|
|
|
procedure AppInit(var ScreenInfo: TScreenInfo); override;
|
|
procedure AppRun(const ALoop: TApplicationMainLoop); override;
|
|
procedure AppWaitMessage; override;
|
|
procedure AppProcessMessages; override;
|
|
procedure AppTerminate; override;
|
|
procedure AppMinimize; override;
|
|
procedure AppRestore; override;
|
|
procedure AppBringToFront; override;
|
|
procedure AppSetTitle(const ATitle: string); override;
|
|
|
|
function CreateTimer(Interval: integer; TimerFunc: TWSTimerProc): THandle; override;
|
|
function DestroyTimer(TimerHandle: THandle): boolean; override;
|
|
|
|
{todo:}
|
|
function DCGetPixel(CanvasHandle: HDC; X, Y: integer): TGraphicsColor; override;
|
|
procedure DCSetPixel(CanvasHandle: HDC; X, Y: integer; AColor: TGraphicsColor); override;
|
|
procedure DCRedraw(CanvasHandle: HDC); override;
|
|
procedure DCSetAntialiasing(CanvasHandle: HDC; AEnabled: Boolean); override;
|
|
procedure SetDesigning(AComponent: TComponent); override;
|
|
|
|
// the winapi compatibility methods
|
|
{$I cocoawinapih.inc}
|
|
// the extra LCL interface methods
|
|
// {$I carbonlclintfh.inc}
|
|
end;
|
|
|
|
var
|
|
CocoaWidgetSet: TCocoaWidgetSet;
|
|
|
|
implementation
|
|
|
|
var
|
|
ScreenContext : TCocoaContext = nil;
|
|
|
|
//todo: a better check!
|
|
|
|
function CheckDC(dc: HDC): TCocoaContext;
|
|
begin
|
|
Result:=TCocoaContext(dc);
|
|
end;
|
|
|
|
function CheckGDIOBJ(obj: HGDIOBJ): TCocoaGDIObject;
|
|
begin
|
|
Result:=TCocoaGDIObject(obj);
|
|
end;
|
|
|
|
|
|
// the implementation of the winapi compatibility methods
|
|
{$I cocoawinapi.inc}
|
|
// the implementation of the extra LCL interface methods
|
|
//{$I Cocoalclintf.inc}
|
|
|
|
|
|
{ TCocoaWidgetSet }
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TCocoaWidgetSet.AppInit
|
|
Params: ScreenInfo
|
|
|
|
Initialize Carbon Widget Set
|
|
------------------------------------------------------------------------------}
|
|
procedure TCocoaWidgetSet.AppInit(var ScreenInfo: TScreenInfo);
|
|
begin
|
|
{$IFDEF VerboseObject}
|
|
DebugLn('TCocoaWidgetSet.AppInit');
|
|
{$ENDIF}
|
|
|
|
delegate:=TCocoaAppDelegate.alloc;
|
|
|
|
{ Creates the application NSApp object }
|
|
NsApp := NSApplication.sharedApplication;
|
|
NSApp.setDelegate(delegate);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TCocoaWidgetSet.AppRun
|
|
Params: ALoop
|
|
------------------------------------------------------------------------------}
|
|
procedure TCocoaWidgetSet.AppRun(const ALoop: TApplicationMainLoop);
|
|
begin
|
|
{$IFDEF VerboseObject}
|
|
DebugLn('TCocoaWidgetSet.AppRun');
|
|
{$ENDIF}
|
|
|
|
{ Enters main message loop }
|
|
NSApp.run;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TCocoaWidgetSet.AppProcessMessages
|
|
|
|
Handle all pending messages
|
|
------------------------------------------------------------------------------}
|
|
procedure TCocoaWidgetSet.AppProcessMessages;
|
|
var
|
|
event : NSEvent;
|
|
begin
|
|
{$IFDEF VerboseObject}
|
|
DebugLn('TCocoaWidgetSet.AppProcessMessages');
|
|
{$ENDIF}
|
|
|
|
event:=NSApp.nextEventMatchingMask_untilDate_inMode_dequeue(NSAnyEventMask, nil, NSDefaultRunLoopMode, true);
|
|
NSApp.sendEvent(event);
|
|
|
|
{$IFDEF VerboseObject}
|
|
DebugLn('TCocoaWidgetSet.AppProcessMessages END');
|
|
{$ENDIF}
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TCocoaWidgetSet.AppWaitMessage
|
|
|
|
Passes execution control to Cocoa
|
|
------------------------------------------------------------------------------}
|
|
procedure TCocoaWidgetSet.AppWaitMessage;
|
|
var
|
|
event : NSEvent;
|
|
begin
|
|
{$IFDEF VerboseObject}
|
|
DebugLn('TCocoaWidgetSet.AppWaitMessage');
|
|
{$ENDIF}
|
|
event:=NSApp.nextEventMatchingMask_untilDate_inMode_dequeue(NSAnyEventMask, NSDate.distantFuture, NSDefaultRunLoopMode, true);
|
|
NSApp.sendEvent(event);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TCocoaWidgetSet.Create
|
|
|
|
Constructor for the class
|
|
------------------------------------------------------------------------------}
|
|
constructor TCocoaWidgetSet.Create;
|
|
begin
|
|
CocoaWidgetSet := Self;
|
|
inherited Create;
|
|
FTerminating := False;
|
|
|
|
{ Creates the AutoreleasePool }
|
|
pool := NSAutoreleasePool(NSAutoreleasePool.alloc).init;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TCocoaWidgetSet.Destroy
|
|
|
|
Destructor for the class
|
|
------------------------------------------------------------------------------}
|
|
destructor TCocoaWidgetSet.Destroy;
|
|
begin
|
|
inherited Destroy;
|
|
CocoaWidgetSet := nil;
|
|
|
|
{ Releases the AutoreleasePool }
|
|
pool.release;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TCocoaWidgetSet.AppTerminate
|
|
|
|
Tells Carbon to halt the application
|
|
------------------------------------------------------------------------------}
|
|
procedure TCocoaWidgetSet.AppTerminate;
|
|
begin
|
|
if FTerminating then Exit;
|
|
{$IFDEF VerboseObject}
|
|
DebugLn('TCocoaWidgetSet.AppTerminate');
|
|
{$ENDIF}
|
|
|
|
NSApp.terminate(nil);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TCocoaWidgetSet.AppMinimize
|
|
|
|
Minimizes the whole application to the taskbar
|
|
------------------------------------------------------------------------------}
|
|
procedure TCocoaWidgetSet.AppMinimize;
|
|
begin
|
|
{$IFDEF VerboseObject}
|
|
DebugLn('TCocoaWidgetSet.AppMinimize');
|
|
{$ENDIF}
|
|
NSApp.miniaturizeAll(nil);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TCocoaWidgetSet.AppRestore
|
|
|
|
Restores the whole minimized application from the taskbar
|
|
------------------------------------------------------------------------------}
|
|
procedure TCocoaWidgetSet.AppRestore;
|
|
begin
|
|
{$IFDEF VerboseObject}
|
|
DebugLn('TCocoaWidgetSet.AppRestore');
|
|
{$ENDIF}
|
|
NSApp.activateIgnoringOtherApps(False);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TCocoaWidgetSet.AppBringToFront
|
|
|
|
Brings the entire application on top of all other non-topmost programs
|
|
------------------------------------------------------------------------------}
|
|
procedure TCocoaWidgetSet.AppBringToFront;
|
|
begin
|
|
{$IFDEF VerboseObject}
|
|
DebugLn('TCocoaWidgetSet.AppBringToFront');
|
|
{$ENDIF}
|
|
NSApp.activateIgnoringOtherApps(True);
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TCocoaWidgetSet.AppSetTitle
|
|
Params: ATitle - New application title
|
|
|
|
Changes the application title
|
|
------------------------------------------------------------------------------}
|
|
procedure TCocoaWidgetSet.AppSetTitle(const ATitle: string);
|
|
var
|
|
ns: NSString;
|
|
begin
|
|
if not Assigned(NSApp.dockTile) then Exit;
|
|
//todo: setBadgeLabel is for 10.5 only, should be removed
|
|
if NSApp.dockTile.respondsToSelector_(objcselector('setBadgeLabel:')) then begin
|
|
ns := NSStringUtf8(ATitle);
|
|
NSApp.dockTile.setBadgeLabel(NSStringUtf8(ATitle));
|
|
ns.release;
|
|
end;
|
|
end;
|
|
|
|
function TCocoaWidgetSet.CreateTimer(Interval: integer; TimerFunc: TWSTimerProc): THandle;
|
|
var
|
|
timer : NSTimer;
|
|
user : TCocoaTimerObject;
|
|
begin
|
|
{$IFDEF VerboseObject}
|
|
DebugLn('TCocoaWidgetSet.CreateTimer');
|
|
{$ENDIF}
|
|
user:=TCocoaTimerObject.initWithFunc(TimerFunc);
|
|
|
|
timer:=NSTimer.timerWithTimeInterval_target_selector_userInfo_repeats(
|
|
Interval/1000, user, objcselector(user.timerEvent), user, True);
|
|
|
|
NSRunLoop.currentRunLoop.addTimer_forMode(timer, NSDefaultRunLoopMode);
|
|
|
|
{user is retained (twice, because it's target), by the timer and }
|
|
{released (twice) on timer invalidation}
|
|
user.release;
|
|
|
|
Result:=THandle(timer);
|
|
end;
|
|
|
|
function TCocoaWidgetSet.DestroyTimer(TimerHandle: THandle): boolean;
|
|
var
|
|
obj : NSObject;
|
|
begin
|
|
{$IFDEF VerboseObject}
|
|
DebugLn('TCocoaWidgetSet.DestroyTimer');
|
|
{$ENDIF}
|
|
obj:=NSObject(TimerHandle);
|
|
try
|
|
Result:= Assigned(obj) and obj.isKindOfClass_(NSTimer);
|
|
except
|
|
Result:=false;
|
|
end;
|
|
if not Result then Exit;
|
|
NSTimer(obj).invalidate;
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TCocoaWidgetSet.GetAppHandle
|
|
Returns: Returns NSApp object, created via NSApplication.sharedApplication
|
|
------------------------------------------------------------------------------}
|
|
function TCocoaWidgetSet.GetAppHandle: THandle;
|
|
begin
|
|
Result:=THandle(NSApp);
|
|
end;
|
|
|
|
function TCocoaWidgetSet.DCGetPixel(CanvasHandle: HDC; X, Y: integer): TGraphicsColor;
|
|
begin
|
|
Result:=0;
|
|
end;
|
|
|
|
procedure TCocoaWidgetSet.DCSetPixel(CanvasHandle: HDC; X, Y: integer; AColor: TGraphicsColor);
|
|
begin
|
|
|
|
end;
|
|
|
|
procedure TCocoaWidgetSet.DCRedraw(CanvasHandle: HDC);
|
|
begin
|
|
|
|
end;
|
|
|
|
procedure TCocoaWidgetSet.DCSetAntialiasing(CanvasHandle: HDC; AEnabled: Boolean);
|
|
begin
|
|
inherited DCSetAntialiasing(CanvasHandle, AEnabled);
|
|
end;
|
|
|
|
procedure TCocoaWidgetSet.SetDesigning(AComponent: TComponent);
|
|
begin
|
|
|
|
end;
|
|
|
|
{------------------------------------------------------------------------------
|
|
Method: TCocoaWidgetSet.LCLPlatform
|
|
Returns: lpCocoa - enum value for Cocoa widgetset
|
|
------------------------------------------------------------------------------}
|
|
function TCocoaWidgetSet.LCLPlatform: TLCLPlatform;
|
|
begin
|
|
Result:= lpCocoa;
|
|
end;
|
|
|
|
procedure InternalInit;
|
|
begin
|
|
end;
|
|
|
|
procedure InternalFinal;
|
|
begin
|
|
if Assigned(ScreenContext) then ScreenContext.Free;
|
|
end;
|
|
|
|
|
|
{ TCocoaAppDelegate }
|
|
|
|
function TCocoaAppDelegate.applicationShouldTerminate(sender: NSApplication): NSApplicationTerminateReply;
|
|
begin
|
|
Result := NSTerminateNow;
|
|
end;
|
|
|
|
{ TCocoaTimerObject }
|
|
|
|
procedure TCocoaTimerObject.timerEvent;
|
|
begin
|
|
if Assigned(@func) then func;
|
|
end;
|
|
|
|
class function TCocoaTimerObject.initWithFunc(afunc: TWSTimerProc): TCocoaTimerObject;
|
|
begin
|
|
Result:=alloc;
|
|
Result.func:=afunc;
|
|
end;
|
|
|
|
initialization
|
|
// {$I Cocoaimages.lrs}
|
|
InternalInit;
|
|
|
|
finalization
|
|
InternalFinal;
|
|
|
|
end.
|