lazarus/lcl/interfaces/cocoa/cocoaprivate.pp

564 lines
14 KiB
ObjectPascal

{ $Id: $}
{ --------------------------------------------
cocoaprivate.pp - Cocoa internal classes
--------------------------------------------
This unit contains the private classhierarchy for the Cocoa implemetations
*****************************************************************************
* *
* 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 CocoaPrivate;
{$mode objfpc}{$H+}
{$modeswitch objectivec1}
interface
uses
// rtl+ftl
Types, Classes, SysUtils,
// Libs
MacOSAll, CocoaAll, CocoaUtils;
type
{ LCLObjectExtension }
LCLObjectExtension = objccategory(NSObject)
function lclIsEnabled: Boolean; message 'lclIsEnabled';
procedure lclSetEnabled(AEnabled: Boolean); message 'lclSetEnabled:';
function lclIsVisible: Boolean; message 'lclIsVisible';
procedure lclInvalidateRect(const r: TRect); message 'lclInvalidateRect:';
procedure lclInvalidate; message 'lclInvalidate';
procedure lclRelativePos(var Left, Top: Integer); message 'lclRelativePos::';
procedure lclLocalToScreen(var X,Y: Integer); message 'lclLocalToScreen::';
function lclParent: id; message 'lclParent';
function lclFrame: TRect; message 'lclFrame';
procedure lclSetFrame(const r: TRect); message 'lclSetFrame:';
function lclClientFrame: TRect; message 'lclClientFrame';
end;
{ LCLViewExtension }
LCLViewExtension = objccategory(NSView)
function lclIsVisible: Boolean; message 'lclIsVisible';
procedure lclInvalidateRect(const r: TRect); message 'lclInvalidateRect:';
procedure lclInvalidate; message 'lclInvalidate';
procedure lclLocalToScreen(var X,Y: Integer); message 'lclLocalToScreen::';
function lclParent: id; message 'lclParent';
function lclFrame: TRect; message 'lclFrame';
procedure lclSetFrame(const r: TRect); message 'lclSetFrame:';
function lclClientFrame: TRect; message 'lclClientFrame';
end;
{ LCLControlExtension }
LCLControlExtension = objccategory(NSControl)
function lclIsEnabled: Boolean; message 'lclIsEnabled';
procedure lclSetEnabled(AEnabled: Boolean); message 'lclSetEnabled:';
end;
{ LCLWindowExtension }
LCLWindowExtension = objccategory(NSWindow)
function lclIsVisible: Boolean; message 'lclIsVisible';
procedure lclInvalidateRect(const r: TRect); message 'lclInvalidateRect:';
procedure lclInvalidate; message 'lclInvalidate';
procedure lclLocalToScreen(var X,Y: Integer); message 'lclLocalToScreen::';
function lclFrame: TRect; message 'lclFrame';
procedure lclSetFrame(const r: TRect); message 'lclSetFrame:';
function lclClientFrame: TRect; message 'lclClientFrame';
end;
{ TCommonCallback }
TCommonCallback = class(TObject)
public
Owner : NSObject;
constructor Create(AOwner: NSObject);
procedure MouseDown(x,y: Integer); virtual; abstract;
procedure MouseUp(x,y: Integer); virtual; abstract;
procedure MouseClick(ClickCount: Integer); virtual; abstract;
procedure MouseMove(x,y: Integer); virtual; abstract;
procedure Draw(ctx: NSGraphicsContext; const bounds, dirty: NSRect); virtual; abstract;
end;
{ TWindowCallback }
TWindowCallback = class(TObject)
public
Owner : NSWindow;
constructor Create(AOwner: NSWindow);
procedure Activate; virtual; abstract;
procedure Deactivate; virtual; abstract;
procedure CloseQuery(var CanClose: Boolean); virtual; abstract;
procedure Close; virtual; abstract;
procedure Resize; virtual; abstract;
end;
{ TCocoaButton }
TCocoaButton = objcclass(NSButton)
protected
procedure actionButtonClick(sender: NSObject); message 'actionButtonClick:';
public
callback : TCommonCallback;
function initWithFrame(frameRect: NSRect): id; override;
function acceptsFirstResponder: Boolean; override;
procedure mouseDown(event: NSEvent); override;
procedure mouseDragged(event: NSEvent); override;
procedure mouseEntered(event: NSEvent); override;
procedure mouseExited(event: NSEvent); override;
procedure mouseMoved(event: NSEvent); override;
procedure mouseUp(event: NSEvent); override;
end;
TCocoaTextField = objcclass(NSTextField)
callback : TCommonCallback;
function acceptsFirstResponder: Boolean; override;
end;
{ TCocoaSecureTextField }
TCocoaSecureTextField = objcclass(NSSecureTextField)
callback : TCommonCallback;
function acceptsFirstResponder: Boolean; override;
end;
TCocoaTextView = objcclass(NSTextView)
callback : TCommonCallback;
function acceptsFirstResponder: Boolean; override;
end;
{ TCocoaWindow }
TCocoaWindow = objcclass(NSWindow)
protected
function windowShouldClose(sender : id): LongBool; message 'windowShouldClose:';
procedure windowWillClose(notification: NSNotification); message 'windowWillClose:';
procedure windowDidBecomeKey(notification: NSNotification); message 'windowDidBecomeKey:';
procedure windowDidResignKey(notification: NSNotification); message 'windowDidResignKey:';
procedure windowDidResize(notification: NSNotification); message 'windowDidResize:';
public
callback : TCommonCallback;
wincallback : TWindowCallback;
function acceptsFirstResponder: Boolean; override;
procedure mouseUp(event: NSEvent); override;
procedure mouseDown(event: NSEvent); override;
procedure mouseDragged(event: NSEvent); override;
procedure mouseEntered(event: NSEvent); override;
procedure mouseExited(event: NSEvent); override;
procedure mouseMoved(event: NSEvent); override;
end;
{ TCocoaCustomControl }
TCocoaCustomControl = objcclass(NSControl)
callback : TCommonCallback;
procedure drawRect(dirtyRect: NSRect); override;
end;
TCocoaScrollView = objcclass(NSScrollView)
callback : TCommonCallback;
end;
implementation
{ TCocoaButton }
procedure TCocoaButton.actionButtonClick(sender: NSObject);
begin
callback.MouseClick(1);
//todo: simulate MouseUp
end;
function TCocoaButton.initWithFrame(frameRect: NSRect): id;
begin
Result:=inherited initWithFrame(frameRect);
if Assigned(Result) then begin
setTarget(Self);
setAction(objcselector('actionButtonClick:'));
end;
end;
function TCocoaButton.acceptsFirstResponder: Boolean;
begin
Result:=true;
end;
procedure TCocoaButton.mouseUp(event: NSEvent);
var
mp : NSPoint;
begin
mp:=event.locationInWindow;
callback.MouseUp(round(mp.x), round(mp.y));
inherited mouseUp(event);
end;
procedure TCocoaButton.mouseDown(event: NSEvent);
var
mp : NSPoint;
begin
mp:=event.locationInWindow;
callback.MouseDown(round(mp.x), round(mp.y));
inherited mouseDown(event);
end;
procedure TCocoaButton.mouseDragged(event: NSEvent);
begin
inherited mouseDragged(event);
end;
procedure TCocoaButton.mouseEntered(event: NSEvent);
begin
inherited mouseEntered(event);
end;
procedure TCocoaButton.mouseExited(event: NSEvent);
begin
inherited mouseExited(event);
end;
procedure TCocoaButton.mouseMoved(event: NSEvent);
begin
inherited mouseMoved(event);
end;
{ TCocoaTextField }
function TCocoaTextField.acceptsFirstResponder: Boolean;
begin
Result:=true;
end;
{ TCocoaTextView }
function TCocoaTextView.acceptsFirstResponder: Boolean;
begin
Result:=true;
end;
{ TCocoaWindow }
function TCocoaWindow.windowShouldClose(sender: id): LongBool;
var
canClose : Boolean;
begin
canClose:=true;
wincallback.CloseQuery(canClose);
Result:=canClose;
end;
procedure TCocoaWindow.windowWillClose(notification: NSNotification);
begin
wincallback.Close;
end;
procedure TCocoaWindow.windowDidBecomeKey(notification: NSNotification);
begin
wincallback.Activate;
end;
procedure TCocoaWindow.windowDidResignKey(notification: NSNotification);
begin
wincallback.Deactivate;
end;
procedure TCocoaWindow.windowDidResize(notification: NSNotification);
begin
wincallback.Resize;
end;
function TCocoaWindow.acceptsFirstResponder: Boolean;
begin
Result:=true;
end;
procedure TCocoaWindow.mouseUp(event: NSEvent);
var
mp : NSPoint;
begin
mp:=event.locationInWindow;
mp.y:=NSView(event.window.contentView).bounds.size.height-mp.y;
callback.MouseUp(round(mp.x), round(mp.y));
inherited mouseUp(event);
end;
procedure TCocoaWindow.mouseDown(event: NSEvent);
var
mp : NSPoint;
begin
mp:=event.locationInWindow;
mp.y:=NSView(event.window.contentView).bounds.size.height-mp.y;
callback.MouseDown(round(mp.x), round(mp.y));
inherited mouseDown(event);
end;
procedure TCocoaWindow.mouseDragged(event: NSEvent);
var
mp : NSPoint;
begin
mp:=event.locationInWindow;
mp.y:=NSView(event.window.contentView).bounds.size.height-mp.y;
callback.MouseMove(round(mp.x), round(mp.y));
inherited mouseMoved(event);
end;
procedure TCocoaWindow.mouseMoved(event: NSEvent);
var
mp : NSPoint;
begin
mp:=event.locationInWindow;
mp.y:=NSView(event.window.contentView).bounds.size.height-mp.y;
callback.MouseMove(round(mp.x), round(mp.y));
inherited mouseMoved(event);
end;
procedure TCocoaWindow.mouseEntered(event: NSEvent);
begin
inherited mouseEntered(event);
end;
procedure TCocoaWindow.mouseExited(event: NSEvent);
begin
inherited mouseExited(event);
end;
{ TCommonCallback }
constructor TCommonCallback.Create(AOwner: NSObject);
begin
Owner:=AOwner;
end;
{ TCocoaSecureTextField }
function TCocoaSecureTextField.acceptsFirstResponder: Boolean;
begin
Result:=True;
end;
{ TWindowCallback }
constructor TWindowCallback.Create(AOwner: NSWindow);
begin
Owner:=AOwner;
end;
{ TCocoaCustomControl }
procedure TCocoaCustomControl.drawRect(dirtyRect:NSRect);
begin
inherited drawRect(dirtyRect);
callback.Draw(NSGraphicsContext.currentContext, bounds, dirtyRect);
end;
{ LCLObjectExtension }
function LCLObjectExtension.lclIsEnabled:Boolean;
begin
Result:=False;
end;
procedure LCLObjectExtension.lclSetEnabled(AEnabled:Boolean);
begin
end;
function LCLObjectExtension.lclIsVisible:Boolean;
begin
Result:=False;
end;
procedure LCLObjectExtension.lclInvalidateRect(const r:TRect);
begin
end;
procedure LCLObjectExtension.lclInvalidate;
begin
end;
procedure LCLObjectExtension.lclRelativePos(var Left,Top:Integer);
begin
end;
procedure LCLObjectExtension.lclLocalToScreen(var X,Y:Integer);
begin
end;
function LCLObjectExtension.lclParent:id;
begin
Result:=nil;
end;
function LCLObjectExtension.lclFrame:TRect;
begin
FillChar(Result, sizeof(Result), 0);
end;
procedure LCLObjectExtension.lclSetFrame(const r:TRect);
begin
end;
function LCLObjectExtension.lclClientFrame:TRect;
begin
FillChar(Result, sizeof(Result), 0);
end;
{ LCLControlExtension }
function RectToViewCoord(view: NSView; const r: TRect): NSRect;
var
b: NSRect;
begin
if not Assigned(view) then Exit;
b:=view.bounds;
Result.origin.x:=r.Left;
Result.origin.y:=b.size.height-r.Top;
Result.size.width:=r.Right-r.Left;
Result.size.height:=r.Bottom-r.Top;
end;
function LCLControlExtension.lclIsEnabled:Boolean;
begin
Result:=IsEnabled;
end;
procedure LCLControlExtension.lclSetEnabled(AEnabled:Boolean);
begin
SetEnabled(AEnabled);
end;
function LCLViewExtension.lclIsVisible:Boolean;
begin
Result:=not isHidden;
end;
procedure LCLViewExtension.lclInvalidateRect(const r:TRect);
begin
setNeedsDisplayInRect(RectToViewCoord(Self, r));
end;
procedure LCLViewExtension.lclInvalidate;
begin
setNeedsDisplay_(True);
end;
procedure LCLViewExtension.lclLocalToScreen(var X,Y:Integer);
begin
end;
function LCLViewExtension.lclParent:id;
begin
Result:=superView;
end;
function LCLViewExtension.lclFrame: TRect;
var
v : NSView;
begin
v:=superview;
if Assigned(v)
then NSToLCLRect(frame, v.frame.size.height, Result)
else NSToLCLRect(frame, Result);
end;
procedure LCLViewExtension.lclSetFrame(const r:TRect);
var
ns : NSRect;
begin
if Assigned(superview)
then LCLToNSRect(r, superview.frame.size.height, ns)
else LCLToNSRect(r, ns);
setFrame(ns);
end;
function LCLViewExtension.lclClientFrame:TRect;
var
r: NSRect;
begin
r:=bounds;
Result.Left:=0;
Result.Top:=0;
Result.Right:=Round(r.size.width);
Result.Bottom:=Round(r.size.height);
end;
{ LCLWindowExtension }
function LCLWindowExtension.lclIsVisible:Boolean;
begin
Result:=isVisible;
end;
procedure LCLWindowExtension.lclInvalidateRect(const r:TRect);
begin
contentView.lclInvalidateRect(r);
end;
procedure LCLWindowExtension.lclInvalidate;
begin
contentView.lclInvalidate;
end;
procedure LCLWindowExtension.lclLocalToScreen(var X,Y:Integer);
var
f : NSRect;
begin
if Assigned(screen) then begin
f:=frame;
x:=Round(f.origin.x+x);
y:=Round(screen.frame.size.height-f.size.height-f.origin.y);
end;
end;
function LCLWindowExtension.lclFrame:TRect;
begin
if Assigned(screen)
then NSToLCLRect(frame, screen.frame.size.height, Result)
else NSToLCLRect(frame, Result);
end;
procedure LCLWindowExtension.lclSetFrame(const r:TRect);
var
ns : NSREct;
begin
if Assigned(screen)
then LCLToNSRect(r, screen.frame.size.height, ns)
else LCLToNSRect(r, ns);
setFrame_display(ns, isVisible);
end;
function LCLWindowExtension.lclClientFrame:TRect;
var
wr : NSRect;
b : NSRect;
begin
wr:=frame;
b:=contentView.frame;
Result.Left:=Round(b.origin.x);
Result.Top:=Round(wr.size.height-b.origin.y);
Result.Right:=Round(b.origin.x+b.size.width);
Result.Bottom:=Round(Result.Top+b.size.height);
end;
end.