lazarus/lcl/interfaces/cocoa/cocoacursor.pas

171 lines
3.7 KiB
ObjectPascal

unit CocoaCursor;
{$mode ObjFPC}{$H+}
{$modeswitch objectivec1}
interface
uses
Classes, SysUtils,
Controls, Forms,
CocoaAll, CocoaUtils, CocoaGDIObjects;
type
{ TCocoaCursor }
TCocoaCursor = class(TObject)
strict private
FStandard: Boolean;
FBitmap: TCocoaBitmap;
FCursor: NSCursor;
public
constructor CreateStandard(const ACursor: NSCursor);
constructor CreateFromBitmap(const ABitmap: TCocoaBitmap; const hotSpot: NSPoint);
constructor CreateFromCustomCursor(const ACursor: NSCursor);
destructor Destroy; override;
procedure SetCursor;
property Cursor: NSCursor read FCursor;
property Standard: Boolean read FStandard;
end;
{ TCursorHelper }
TCursorHelper = class
private
_lastCursor: NSCursor;
public
procedure SetNewCursor( newCursor:TCocoaCursor );
procedure ForceSetDefaultCursor;
procedure SetCursorOnActive;
procedure SetScreenCursor;
procedure SetScreenCursorWhenNotDefault;
public
class procedure SetCursorAtMousePos;
end;
function CocoaGetCursorPos(var lpPoint: TPoint ): Boolean;
var
CursorHelper: TCursorHelper;
implementation
function CocoaGetCursorPos(var lpPoint: TPoint ): Boolean;
begin
lpPoint:= ScreenPointFromNSToLCL( NSEvent.mouseLocation );
Result := True;
end;
{ TCocoaCursor }
constructor TCocoaCursor.CreateStandard(const ACursor: NSCursor);
begin
FBitmap := nil;
FCursor := ACursor;
FStandard := True;
end;
constructor TCocoaCursor.CreateFromBitmap(const ABitmap: TCocoaBitmap; const hotSpot: NSPoint);
begin
FBitmap := ABitmap; // takes ownership, no ref count change required
FCursor := NSCursor.alloc.initWithImage_hotSpot(ABitmap.Image, hotSpot);
FStandard := False;
end;
constructor TCocoaCursor.CreateFromCustomCursor(const ACursor: NSCursor);
begin
FCursor := ACursor;
FStandard := False;
end;
destructor TCocoaCursor.Destroy;
begin
FreeAndNil(FBitmap);
if not Standard then
FCursor.release;
inherited;
end;
procedure TCocoaCursor.SetCursor;
begin
FCursor.set_;
end;
{ TCursorHelper }
procedure TCursorHelper.SetNewCursor( newCursor:TCocoaCursor );
var
currentCursor: NSCursor;
begin
currentCursor:= NSCursor.currentCursor;
if (_lastCursor=nil) or (currentCursor=NSCursor.arrowCursor) or (currentCursor=_lastCursor) then
begin
newCursor.SetCursor;
_lastCursor:= newCursor.Cursor;
end;
end;
procedure TCursorHelper.ForceSetDefaultCursor;
var
newCursor: TCocoaCursor;
begin
newCursor:= TCocoaCursor(Screen.Cursors[crDefault]);
newCursor.SetCursor;
_lastCursor:= newCursor.Cursor;
end;
procedure TCursorHelper.SetCursorOnActive;
begin
_lastCursor:= NSCursor.arrowCursor;
if Screen.Cursor<>crDefault then
SetScreenCursor
else
SetCursorAtMousePos;
end;
class procedure TCursorHelper.SetCursorAtMousePos;
var
P: TPoint;
rect: NSRect;
window: NSWindow;
event: NSEvent;
begin
window:= NSAPP.keyWindow;
if not Assigned(window) then
exit;
CocoaGetCursorPos(P);
rect:= NSZeroRect;
rect.origin:= LCLToNSPoint(P, window.screen.frame.size.height);
rect:= window.convertRectFromScreen(rect);
event:= NSEvent.mouseEventWithType_location_modifierFlags_timestamp_windowNumber_context_eventNumber_clickCount_pressure(
NSMouseMoved,
rect.origin, 0, 0,
window.windowNumber, nil, 0, 0, 0);
NSApp.postEvent_atStart(event, true);
end;
procedure TCursorHelper.SetScreenCursor;
begin
_lastCursor:= nil;
TCocoaCursor(Screen.Cursors[Screen.Cursor]).SetCursor;
end;
procedure TCursorHelper.SetScreenCursorWhenNotDefault;
begin
if Screen.Cursor<>crDefault then
SetScreenCursor;
end;
initialization
CursorHelper:= TCursorHelper.Create;
finalization
FreeAndNil(CursorHelper);
end.