File: cocoacursor.pas

package info (click to toggle)
lazarus 4.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 275,760 kB
  • sloc: pascal: 2,341,904; xml: 509,420; makefile: 348,726; cpp: 93,608; sh: 3,387; java: 609; perl: 297; sql: 222; ansic: 137
file content (170 lines) | stat: -rw-r--r-- 3,774 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
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.