mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-06-22 07:28:12 +02:00
171 lines
3.7 KiB
ObjectPascal
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.
|
|
|