1 | // Copyright 2014 The Flutter Authors. All rights reserved. |
---|---|
2 | // Use of this source code is governed by a BSD-style license that can be |
3 | // found in the LICENSE file. |
4 | |
5 | /// @docImport 'package:flutter/material.dart'; |
6 | /// @docImport 'package:flutter/rendering.dart'; |
7 | library; |
8 | |
9 | import 'package:flutter/foundation.dart'; |
10 | import 'package:flutter/gestures.dart'; |
11 | |
12 | import 'system_channels.dart'; |
13 | |
14 | export 'package:flutter/foundation.dart' show DiagnosticLevel, DiagnosticPropertiesBuilder; |
15 | export 'package:flutter/gestures.dart' show PointerEvent; |
16 | |
17 | /// Maintains the state of mouse cursors and manages how cursors are searched |
18 | /// for. |
19 | /// |
20 | /// This is typically created as a global singleton and owned by [MouseTracker]. |
21 | class MouseCursorManager { |
22 | /// Create a [MouseCursorManager] by specifying the fallback cursor. |
23 | /// |
24 | /// The `fallbackMouseCursor` must not be [MouseCursor.defer] (typically |
25 | /// [SystemMouseCursors.basic]). |
26 | MouseCursorManager(this.fallbackMouseCursor) |
27 | : assert(fallbackMouseCursor != MouseCursor.defer); |
28 | |
29 | /// The mouse cursor to use if all cursor candidates choose to defer. |
30 | /// |
31 | /// See also: |
32 | /// |
33 | /// * [MouseCursor.defer], the mouse cursor object to use to defer. |
34 | final MouseCursor fallbackMouseCursor; |
35 | |
36 | /// Returns the active mouse cursor of a device. |
37 | /// |
38 | /// The return value is the last [MouseCursor] activated onto this |
39 | /// device, even if the activation failed. |
40 | /// |
41 | /// Only valid when asserts are enabled. In release builds, always returns |
42 | /// null. |
43 | MouseCursor? debugDeviceActiveCursor(int device) { |
44 | MouseCursor? result; |
45 | assert(() { |
46 | result = _lastSession[device]?.cursor; |
47 | return true; |
48 | }()); |
49 | return result; |
50 | } |
51 | |
52 | final Map<int, MouseCursorSession> _lastSession = <int, MouseCursorSession>{}; |
53 | |
54 | /// Handles the changes that cause a pointer device to have a new list of mouse |
55 | /// cursor candidates. |
56 | /// |
57 | /// This change can be caused by a pointer event, in which case |
58 | /// `triggeringEvent` should not be null, or by other changes, such as when a |
59 | /// widget has moved under a still mouse, which is detected after the current |
60 | /// frame is complete. In either case, `cursorCandidates` should be the list of |
61 | /// cursors at the location of the mouse in hit-test order. |
62 | void handleDeviceCursorUpdate( |
63 | int device, |
64 | PointerEvent? triggeringEvent, |
65 | Iterable<MouseCursor> cursorCandidates, |
66 | ) { |
67 | if (triggeringEvent is PointerRemovedEvent) { |
68 | _lastSession.remove(device); |
69 | return; |
70 | } |
71 | |
72 | final MouseCursorSession? lastSession = _lastSession[device]; |
73 | final MouseCursor nextCursor = _DeferringMouseCursor.firstNonDeferred(cursorCandidates) |
74 | ?? fallbackMouseCursor; |
75 | assert(nextCursor is! _DeferringMouseCursor); |
76 | if (lastSession?.cursor == nextCursor) { |
77 | return; |
78 | } |
79 | |
80 | final MouseCursorSession nextSession = nextCursor.createSession(device); |
81 | _lastSession[device] = nextSession; |
82 | |
83 | lastSession?.dispose(); |
84 | nextSession.activate(); |
85 | } |
86 | } |
87 | |
88 | /// Manages the duration that a pointing device should display a specific mouse |
89 | /// cursor. |
90 | /// |
91 | /// While [MouseCursor] classes describe the kind of cursors, [MouseCursorSession] |
92 | /// classes represents a continuous use of the cursor on a pointing device. The |
93 | /// [MouseCursorSession] classes can be stateful. For example, a cursor that |
94 | /// needs to load resources might want to set a temporary cursor first, then |
95 | /// switch to the correct cursor after the load is completed. |
96 | /// |
97 | /// A [MouseCursorSession] has the following lifecycle: |
98 | /// |
99 | /// * When a pointing device should start displaying a cursor, [MouseTracker] |
100 | /// creates a session by calling [MouseCursor.createSession] on the target |
101 | /// cursor, and stores it in a table associated with the device. |
102 | /// * [MouseTracker] then immediately calls the session's [activate], where the |
103 | /// session should fetch resources and make system calls. |
104 | /// * When the pointing device should start displaying a different cursor, |
105 | /// [MouseTracker] calls [dispose] on this session. After [dispose], this session |
106 | /// will no longer be used in the future. |
107 | abstract class MouseCursorSession { |
108 | /// Create a session. |
109 | MouseCursorSession(this.cursor, this.device); |
110 | |
111 | /// The cursor that created this session. |
112 | final MouseCursor cursor; |
113 | |
114 | /// The device ID of the pointing device. |
115 | final int device; |
116 | |
117 | /// Override this method to do the work of changing the cursor of the device. |
118 | /// |
119 | /// Called right after this session is created. |
120 | /// |
121 | /// This method has full control over the cursor until the [dispose] call, and |
122 | /// can make system calls to change the pointer cursor as many times as |
123 | /// necessary (usually through [SystemChannels.mouseCursor]). It can also |
124 | /// collect resources, and store the result in this object. |
125 | @protected |
126 | Future<void> activate(); |
127 | |
128 | /// Called when device stops displaying the cursor. |
129 | /// |
130 | /// After this call, this session instance will no longer be used in the |
131 | /// future. |
132 | /// |
133 | /// When implementing this method in subclasses, you should release resources |
134 | /// and prevent [activate] from causing side effects after disposal. |
135 | @protected |
136 | void dispose(); |
137 | } |
138 | |
139 | /// An interface for mouse cursor definitions. |
140 | /// |
141 | /// A mouse cursor is a graphical image on the screen that echoes the movement |
142 | /// of a pointing device, such as a mouse or a stylus. A [MouseCursor] object |
143 | /// defines a kind of mouse cursor, such as an arrow, a pointing hand, or an |
144 | /// I-beam. |
145 | /// |
146 | /// During the painting phase, [MouseCursor] objects are assigned to regions on |
147 | /// the screen via annotations. Later during a device update (e.g. when a mouse |
148 | /// moves), [MouseTracker] finds the _active cursor_ of each mouse device, which |
149 | /// is the front-most region associated with the position of each mouse cursor, |
150 | /// or defaults to [SystemMouseCursors.basic] if no cursors are associated with |
151 | /// the position. [MouseTracker] changes the cursor of the pointer if the new |
152 | /// active cursor is different from the previous active cursor, whose effect is |
153 | /// defined by the session created by [createSession]. |
154 | /// |
155 | /// ## Cursor classes |
156 | /// |
157 | /// A [SystemMouseCursor] is a cursor that is natively supported by the |
158 | /// platform that the program is running on. All supported system mouse cursors |
159 | /// are enumerated in [SystemMouseCursors]. |
160 | /// |
161 | /// ## Using cursors |
162 | /// |
163 | /// A [MouseCursor] object is used by being assigned to a [MouseRegion] or |
164 | /// another widget that exposes the [MouseRegion] API, such as |
165 | /// [InkResponse.mouseCursor]. |
166 | /// |
167 | /// {@tool dartpad} |
168 | /// This sample creates a rectangular region that is wrapped by a [MouseRegion] |
169 | /// with a system mouse cursor. The mouse pointer becomes an I-beam when |
170 | /// hovering over the region. |
171 | /// |
172 | /// ** See code in examples/api/lib/services/mouse_cursor/mouse_cursor.0.dart ** |
173 | /// {@end-tool} |
174 | /// |
175 | /// Assigning regions with mouse cursors on platforms that do not support mouse |
176 | /// cursors, or when there are no mice connected, will have no effect. |
177 | /// |
178 | /// ## Related classes |
179 | /// |
180 | /// [MouseCursorSession] represents the duration when a pointing device displays |
181 | /// a cursor, and defines the states and behaviors of the cursor. Every mouse |
182 | /// cursor class usually has a corresponding [MouseCursorSession] class. |
183 | /// |
184 | /// [MouseCursorManager] is a class that adds the feature of changing |
185 | /// cursors to [MouseTracker], which tracks the relationship between mouse |
186 | /// devices and annotations. [MouseCursorManager] is usually used as a part |
187 | /// of [MouseTracker]. |
188 | @immutable |
189 | abstract class MouseCursor with Diagnosticable { |
190 | /// Abstract const constructor. This constructor enables subclasses to provide |
191 | /// const constructors so that they can be used in const expressions. |
192 | const MouseCursor(); |
193 | |
194 | /// Associate a pointing device to this cursor. |
195 | /// |
196 | /// A mouse cursor class usually has a corresponding [MouseCursorSession] |
197 | /// class, and instantiates such class in this method. |
198 | /// |
199 | /// This method is called each time a pointing device starts displaying this |
200 | /// cursor. A given cursor can be displayed by multiple devices at the same |
201 | /// time, in which case this method will be called separately for each device. |
202 | @protected |
203 | @factory |
204 | MouseCursorSession createSession(int device); |
205 | |
206 | /// A very short description of the mouse cursor. |
207 | /// |
208 | /// The [debugDescription] should be a few words that can describe this cursor |
209 | /// to make debug information more readable. It is returned as the [toString] |
210 | /// when the diagnostic level is at or above [DiagnosticLevel.info]. |
211 | /// |
212 | /// The [debugDescription] must not be empty. |
213 | String get debugDescription; |
214 | |
215 | @override |
216 | String toString({DiagnosticLevel minLevel = DiagnosticLevel.info}) { |
217 | final String debugDescription = this.debugDescription; |
218 | if (minLevel.index >= DiagnosticLevel.info.index) { |
219 | return debugDescription; |
220 | } |
221 | return super.toString(minLevel: minLevel); |
222 | } |
223 | |
224 | /// A special class that indicates that the region with this cursor defers the |
225 | /// choice of cursor to the next region behind it. |
226 | /// |
227 | /// When an event occurs, [MouseTracker] will update each pointer's cursor by |
228 | /// finding the list of regions that contain the pointer's location, from front |
229 | /// to back in hit-test order. The pointer's cursor will be the first cursor in |
230 | /// the list that is not a [MouseCursor.defer]. |
231 | static const MouseCursor defer = _DeferringMouseCursor._(); |
232 | |
233 | /// A special value that doesn't change cursor by itself, but make a region |
234 | /// that blocks other regions behind it from changing the cursor. |
235 | /// |
236 | /// When a pointer enters a region with a cursor of [uncontrolled], the pointer |
237 | /// retains its previous cursor and keeps so until it moves out of the region. |
238 | /// Technically, this region absorb the mouse cursor hit test without changing |
239 | /// the pointer's cursor. |
240 | /// |
241 | /// This is useful in a region that displays a platform view, which let the |
242 | /// operating system handle pointer events and change cursors accordingly. To |
243 | /// achieve this, the region's cursor must not be any Flutter cursor, since |
244 | /// that might overwrite the system request upon pointer entering; the cursor |
245 | /// must not be null either, since that allows the widgets behind the region to |
246 | /// change cursors. |
247 | static const MouseCursor uncontrolled = _NoopMouseCursor._(); |
248 | } |
249 | |
250 | class _DeferringMouseCursor extends MouseCursor { |
251 | const _DeferringMouseCursor._(); |
252 | |
253 | @override |
254 | MouseCursorSession createSession(int device) { |
255 | assert(false, '_DeferringMouseCursor can not create a session'); |
256 | throw UnimplementedError(); |
257 | } |
258 | |
259 | @override |
260 | String get debugDescription => 'defer'; |
261 | |
262 | /// Returns the first cursor that is not a [MouseCursor.defer]. |
263 | static MouseCursor? firstNonDeferred(Iterable<MouseCursor> cursors) { |
264 | for (final MouseCursor cursor in cursors) { |
265 | if (cursor != MouseCursor.defer) { |
266 | return cursor; |
267 | } |
268 | } |
269 | return null; |
270 | } |
271 | } |
272 | |
273 | class _NoopMouseCursorSession extends MouseCursorSession { |
274 | _NoopMouseCursorSession(_NoopMouseCursor super.cursor, super.device); |
275 | |
276 | @override |
277 | Future<void> activate() async { /* Nothing */ } |
278 | |
279 | @override |
280 | void dispose() { /* Nothing */ } |
281 | } |
282 | |
283 | /// A mouse cursor that doesn't change the cursor when activated. |
284 | /// |
285 | /// Although setting a region's cursor to [_NoopMouseCursor] doesn't change the |
286 | /// cursor, it blocks regions behind it from changing the cursor, in contrast to |
287 | /// setting the cursor to null. More information about the usage of this class |
288 | /// can be found at [MouseCursor.uncontrolled]. |
289 | /// |
290 | /// To use this class, use [MouseCursor.uncontrolled]. Directly |
291 | /// instantiating this class is not allowed. |
292 | class _NoopMouseCursor extends MouseCursor { |
293 | // Application code shouldn't directly instantiate this class, since its only |
294 | // instance is accessible at [SystemMouseCursors.releaseControl]. |
295 | const _NoopMouseCursor._(); |
296 | |
297 | @override |
298 | @protected |
299 | _NoopMouseCursorSession createSession(int device) => _NoopMouseCursorSession(this, device); |
300 | |
301 | @override |
302 | String get debugDescription => 'uncontrolled'; |
303 | } |
304 | |
305 | class _SystemMouseCursorSession extends MouseCursorSession { |
306 | _SystemMouseCursorSession(SystemMouseCursor super.cursor, super.device); |
307 | |
308 | @override |
309 | SystemMouseCursor get cursor => super.cursor as SystemMouseCursor; |
310 | |
311 | @override |
312 | Future<void> activate() { |
313 | return SystemChannels.mouseCursor.invokeMethod<void>( |
314 | 'activateSystemCursor', |
315 | <String, dynamic>{ |
316 | 'device': device, |
317 | 'kind': cursor.kind, |
318 | }, |
319 | ); |
320 | } |
321 | |
322 | @override |
323 | void dispose() { /* Nothing */ } |
324 | } |
325 | |
326 | /// A mouse cursor that is natively supported on the platform that the |
327 | /// application is running on. |
328 | /// |
329 | /// System cursors can be used without external resources, and their appearances |
330 | /// match the experience of native apps. Examples of system cursors are a |
331 | /// pointing arrow, a pointing hand, a double arrow for resizing, or a text |
332 | /// I-beam, etc. |
333 | /// |
334 | /// An instance of [SystemMouseCursor] refers to one cursor from each platform |
335 | /// that represents the same concept, such as being text, being clickable, |
336 | /// or being a forbidden operation. Since the set of system cursors supported by |
337 | /// each platform varies, multiple instances can correspond to the same system |
338 | /// cursor. |
339 | /// |
340 | /// Each cursor is noted with its corresponding native cursors on each platform: |
341 | /// |
342 | /// * Android: API name in Java |
343 | /// * Web: CSS cursor |
344 | /// * Windows: Win32 API |
345 | /// * Windows UWP: WinRT API, `winrt::Windows::UI::Core::CoreCursorType` |
346 | /// * Linux: GDK, `gdk_cursor_new_from_name` |
347 | /// * macOS: API name in Objective C |
348 | /// |
349 | /// If the platform that the application is running on is not listed for a cursor, |
350 | /// using this cursor falls back to [SystemMouseCursors.basic]. |
351 | /// |
352 | /// [SystemMouseCursors] enumerates the complete set of system cursors supported |
353 | /// by Flutter, which are hard-coded in the engine. Therefore, manually |
354 | /// instantiating this class is not supported. |
355 | class SystemMouseCursor extends MouseCursor { |
356 | // Application code shouldn't directly instantiate system mouse cursors, since |
357 | // the supported system cursors are enumerated in [SystemMouseCursors]. |
358 | const SystemMouseCursor._({ |
359 | required this.kind, |
360 | }); |
361 | |
362 | /// A string that identifies the kind of the cursor. |
363 | /// |
364 | /// The interpretation of [kind] is platform-dependent. |
365 | final String kind; |
366 | |
367 | @override |
368 | String get debugDescription => '${objectRuntimeType(this, 'SystemMouseCursor')} ($kind )'; |
369 | |
370 | @override |
371 | @protected |
372 | MouseCursorSession createSession(int device) => _SystemMouseCursorSession(this, device); |
373 | |
374 | @override |
375 | bool operator ==(Object other) { |
376 | if (other.runtimeType != runtimeType) { |
377 | return false; |
378 | } |
379 | return other is SystemMouseCursor |
380 | && other.kind == kind; |
381 | } |
382 | |
383 | @override |
384 | int get hashCode => kind.hashCode; |
385 | |
386 | @override |
387 | void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
388 | super.debugFillProperties(properties); |
389 | properties.add(DiagnosticsProperty<String>('kind', kind, level: DiagnosticLevel.debug)); |
390 | } |
391 | } |
392 | |
393 | /// A collection of system [MouseCursor]s. |
394 | /// |
395 | /// System cursors are standard mouse cursors that are provided by the current |
396 | /// platform. They don't require external resources. |
397 | /// |
398 | /// [SystemMouseCursors] is a superset of the system cursors of every platform |
399 | /// that Flutter supports, therefore some of these objects might map to the same |
400 | /// result, or fallback to the [basic] arrow. This mapping is defined by the |
401 | /// Flutter engine. |
402 | /// |
403 | /// The cursors should be named based on the cursors' use cases instead of their |
404 | /// appearance, because different platforms might (although not commonly) use |
405 | /// different shapes for the same use case. |
406 | abstract final class SystemMouseCursors { |
407 | // The mapping in this class must be kept in sync with the following files in |
408 | // the engine: |
409 | // |
410 | // * Android: shell/platform/android/io/flutter/plugin/mouse/MouseCursorPlugin.java |
411 | // * Web: lib/web_ui/lib/src/engine/mouse_cursor.dart |
412 | // * Windows: shell/platform/windows/win32_flutter_window_win32.cc |
413 | // * Windows UWP: shell/platform/windows/win32_flutter_window_winuwp.cc |
414 | // * Linux: shell/platform/linux/fl_mouse_cursor_plugin.cc |
415 | // * macOS: shell/platform/darwin/macos/framework/Source/FlutterMouseCursorPlugin.mm |
416 | |
417 | |
418 | /// Hide the cursor. |
419 | /// |
420 | /// Any cursor other than [none] or [MouseCursor.uncontrolled] unhides the |
421 | /// cursor. |
422 | static const SystemMouseCursor none = SystemMouseCursor._(kind: 'none'); |
423 | |
424 | |
425 | // STATUS |
426 | |
427 | /// The platform-dependent basic cursor. |
428 | /// |
429 | /// Typically the shape of an arrow. |
430 | /// |
431 | /// Corresponds to: |
432 | /// |
433 | /// * Android: TYPE_DEFAULT, TYPE_ARROW |
434 | /// * Web: default |
435 | /// * Windows: IDC_ARROW |
436 | /// * Windows UWP: CoreCursorType::Arrow |
437 | /// * Linux: default |
438 | /// * macOS: arrowCursor |
439 | static const SystemMouseCursor basic = SystemMouseCursor._(kind: 'basic'); |
440 | |
441 | /// A cursor that emphasizes an element being clickable, such as a hyperlink. |
442 | /// |
443 | /// Typically the shape of a pointing hand. |
444 | /// |
445 | /// Corresponds to: |
446 | /// |
447 | /// * Android: TYPE_HAND |
448 | /// * Web: pointer |
449 | /// * Windows: IDC_HAND |
450 | /// * Windows UWP: CoreCursorType::Hand |
451 | /// * Linux: pointer |
452 | /// * macOS: pointingHandCursor |
453 | static const SystemMouseCursor click = SystemMouseCursor._(kind: 'click'); |
454 | |
455 | /// A cursor indicating an operation that will not be carried out. |
456 | /// |
457 | /// Typically the shape of a circle with a diagonal line. May fall back to |
458 | /// [noDrop]. |
459 | /// |
460 | /// Corresponds to: |
461 | /// |
462 | /// * Android: TYPE_NO_DROP |
463 | /// * Web: not-allowed |
464 | /// * Windows: IDC_NO |
465 | /// * Windows UWP: CoreCursorType::UniversalNo |
466 | /// * Linux: not-allowed |
467 | /// * macOS: operationNotAllowedCursor |
468 | /// |
469 | /// See also: |
470 | /// |
471 | /// * [noDrop], which indicates somewhere that the current item may not be |
472 | /// dropped. |
473 | static const SystemMouseCursor forbidden = SystemMouseCursor._(kind: 'forbidden'); |
474 | |
475 | /// A cursor indicating the status that the program is busy and therefore |
476 | /// can not be interacted with. |
477 | /// |
478 | /// Typically the shape of an hourglass or a watch. |
479 | /// |
480 | /// This cursor is not available as a system cursor on macOS. Although macOS |
481 | /// displays a "spinning ball" cursor when busy, it's handled by the OS and not |
482 | /// exposed for applications to choose. |
483 | /// |
484 | /// Corresponds to: |
485 | /// |
486 | /// * Android: TYPE_WAIT |
487 | /// * Windows: IDC_WAIT |
488 | /// * Web: wait |
489 | /// * Linux: wait |
490 | /// |
491 | /// See also: |
492 | /// |
493 | /// * [progress], which is similar to [wait] but the program can still be |
494 | /// interacted with. |
495 | static const SystemMouseCursor wait = SystemMouseCursor._(kind: 'wait'); |
496 | |
497 | /// A cursor indicating the status that the program is busy but can still be |
498 | /// interacted with. |
499 | /// |
500 | /// Typically the shape of an arrow with an hourglass or a watch at the corner. |
501 | /// Does *not* fall back to [wait] if unavailable. |
502 | /// |
503 | /// Corresponds to: |
504 | /// |
505 | /// * Web: progress |
506 | /// * Windows: IDC_APPSTARTING |
507 | /// * Linux: progress |
508 | /// |
509 | /// See also: |
510 | /// |
511 | /// * [wait], which is similar to [progress] but the program can not be |
512 | /// interacted with. |
513 | static const SystemMouseCursor progress = SystemMouseCursor._(kind: 'progress'); |
514 | |
515 | /// A cursor indicating somewhere the user can trigger a context menu. |
516 | /// |
517 | /// Typically the shape of an arrow with a small menu at the corner. |
518 | /// |
519 | /// Corresponds to: |
520 | /// |
521 | /// * Android: TYPE_CONTEXT_MENU |
522 | /// * Web: context-menu |
523 | /// * Linux: context-menu |
524 | /// * macOS: contextualMenuCursor |
525 | static const SystemMouseCursor contextMenu = SystemMouseCursor._(kind: 'contextMenu'); |
526 | |
527 | /// A cursor indicating help information. |
528 | /// |
529 | /// Typically the shape of a question mark, or an arrow therewith. |
530 | /// |
531 | /// Corresponds to: |
532 | /// |
533 | /// * Android: TYPE_HELP |
534 | /// * Windows: IDC_HELP |
535 | /// * Windows UWP: CoreCursorType::Help |
536 | /// * Web: help |
537 | /// * Linux: help |
538 | static const SystemMouseCursor help = SystemMouseCursor._(kind: 'help'); |
539 | |
540 | |
541 | // SELECTION |
542 | |
543 | /// A cursor indicating selectable text. |
544 | /// |
545 | /// Typically the shape of a capital I. |
546 | /// |
547 | /// Corresponds to: |
548 | /// |
549 | /// * Android: TYPE_TEXT |
550 | /// * Web: text |
551 | /// * Windows: IDC_IBEAM |
552 | /// * Windows UWP: CoreCursorType::IBeam |
553 | /// * Linux: text |
554 | /// * macOS: IBeamCursor |
555 | static const SystemMouseCursor text = SystemMouseCursor._(kind: 'text'); |
556 | |
557 | /// A cursor indicating selectable vertical text. |
558 | /// |
559 | /// Typically the shape of a capital I rotated to be horizontal. May fall back |
560 | /// to [text]. |
561 | /// |
562 | /// Corresponds to: |
563 | /// |
564 | /// * Android: TYPE_VERTICAL_TEXT |
565 | /// * Web: vertical-text |
566 | /// * Linux: vertical-text |
567 | /// * macOS: IBeamCursorForVerticalLayout |
568 | static const SystemMouseCursor verticalText = SystemMouseCursor._(kind: 'verticalText'); |
569 | |
570 | /// A cursor indicating selectable table cells. |
571 | /// |
572 | /// Typically the shape of a hollow plus sign. |
573 | /// |
574 | /// Corresponds to: |
575 | /// |
576 | /// * Android: TYPE_CELL |
577 | /// * Web: cell |
578 | /// * Linux: cell |
579 | static const SystemMouseCursor cell = SystemMouseCursor._(kind: 'cell'); |
580 | |
581 | /// A cursor indicating precise selection, such as selecting a pixel in a |
582 | /// bitmap. |
583 | /// |
584 | /// Typically the shape of a crosshair. |
585 | /// |
586 | /// Corresponds to: |
587 | /// |
588 | /// * Android: TYPE_CROSSHAIR |
589 | /// * Web: crosshair |
590 | /// * Windows: IDC_CROSS |
591 | /// * Windows UWP: CoreCursorType::Cross |
592 | /// * Linux: crosshair |
593 | /// * macOS: crosshairCursor |
594 | static const SystemMouseCursor precise = SystemMouseCursor._(kind: 'precise'); |
595 | |
596 | |
597 | // DRAG-AND-DROP |
598 | |
599 | /// A cursor indicating moving something. |
600 | /// |
601 | /// Typically the shape of four-way arrow. May fall back to [allScroll]. |
602 | /// |
603 | /// Corresponds to: |
604 | /// |
605 | /// * Android: TYPE_ALL_SCROLL |
606 | /// * Windows: IDC_SIZEALL |
607 | /// * Windows UWP: CoreCursorType::SizeAll |
608 | /// * Web: move |
609 | /// * Linux: move |
610 | static const SystemMouseCursor move = SystemMouseCursor._(kind: 'move'); |
611 | |
612 | /// A cursor indicating something that can be dragged. |
613 | /// |
614 | /// Typically the shape of an open hand. |
615 | /// |
616 | /// Corresponds to: |
617 | /// |
618 | /// * Android: TYPE_GRAB |
619 | /// * Web: grab |
620 | /// * Linux: grab |
621 | /// * macOS: openHandCursor |
622 | static const SystemMouseCursor grab = SystemMouseCursor._(kind: 'grab'); |
623 | |
624 | /// A cursor indicating something that is being dragged. |
625 | /// |
626 | /// Typically the shape of a closed hand. |
627 | /// |
628 | /// Corresponds to: |
629 | /// |
630 | /// * Android: TYPE_GRABBING |
631 | /// * Web: grabbing |
632 | /// * Linux: grabbing |
633 | /// * macOS: closedHandCursor |
634 | static const SystemMouseCursor grabbing = SystemMouseCursor._(kind: 'grabbing'); |
635 | |
636 | /// A cursor indicating somewhere that the current item may not be dropped. |
637 | /// |
638 | /// Typically the shape of a hand with a [forbidden] sign at the corner. May |
639 | /// fall back to [forbidden]. |
640 | /// |
641 | /// Corresponds to: |
642 | /// |
643 | /// * Android: TYPE_NO_DROP |
644 | /// * Web: no-drop |
645 | /// * Windows: IDC_NO |
646 | /// * Windows UWP: CoreCursorType::UniversalNo |
647 | /// * Linux: no-drop |
648 | /// * macOS: operationNotAllowedCursor |
649 | /// |
650 | /// See also: |
651 | /// |
652 | /// * [forbidden], which indicates an action that will not be carried out. |
653 | static const SystemMouseCursor noDrop = SystemMouseCursor._(kind: 'noDrop'); |
654 | |
655 | /// A cursor indicating that the current operation will create an alias of, or |
656 | /// a shortcut of the item. |
657 | /// |
658 | /// Typically the shape of an arrow with a shortcut icon at the corner. |
659 | /// |
660 | /// Corresponds to: |
661 | /// |
662 | /// * Android: TYPE_ALIAS |
663 | /// * Web: alias |
664 | /// * Linux: alias |
665 | /// * macOS: dragLinkCursor |
666 | static const SystemMouseCursor alias = SystemMouseCursor._(kind: 'alias'); |
667 | |
668 | /// A cursor indicating that the current operation will copy the item. |
669 | /// |
670 | /// Typically the shape of an arrow with a boxed plus sign at the corner. |
671 | /// |
672 | /// Corresponds to: |
673 | /// |
674 | /// * Android: TYPE_COPY |
675 | /// * Web: copy |
676 | /// * Linux: copy |
677 | /// * macOS: dragCopyCursor |
678 | static const SystemMouseCursor copy = SystemMouseCursor._(kind: 'copy'); |
679 | |
680 | /// A cursor indicating that the current operation will result in the |
681 | /// disappearance of the item. |
682 | /// |
683 | /// Typically the shape of an arrow with a cloud of smoke at the corner. |
684 | /// |
685 | /// Corresponds to: |
686 | /// |
687 | /// * macOS: disappearingItemCursor |
688 | static const SystemMouseCursor disappearing = SystemMouseCursor._(kind: 'disappearing'); |
689 | |
690 | |
691 | // RESIZING AND SCROLLING |
692 | |
693 | /// A cursor indicating scrolling in any direction. |
694 | /// |
695 | /// Typically the shape of a dot surrounded by 4 arrows. |
696 | /// |
697 | /// Corresponds to: |
698 | /// |
699 | /// * Android: TYPE_ALL_SCROLL |
700 | /// * Windows: IDC_SIZEALL |
701 | /// * Windows UWP: CoreCursorType::SizeAll |
702 | /// * Web: all-scroll |
703 | /// * Linux: all-scroll |
704 | /// |
705 | /// See also: |
706 | /// |
707 | /// * [move], which indicates moving in any direction. |
708 | static const SystemMouseCursor allScroll = SystemMouseCursor._(kind: 'allScroll'); |
709 | |
710 | /// A cursor indicating resizing an object bidirectionally from its left or |
711 | /// right edge. |
712 | /// |
713 | /// Typically the shape of a bidirectional arrow pointing left and right. |
714 | /// |
715 | /// Corresponds to: |
716 | /// |
717 | /// * Android: TYPE_HORIZONTAL_DOUBLE_ARROW |
718 | /// * Web: ew-resize |
719 | /// * Windows: IDC_SIZEWE |
720 | /// * Windows UWP: CoreCursorType::SizeWestEast |
721 | /// * Linux: ew-resize |
722 | /// * macOS: resizeLeftRightCursor |
723 | static const SystemMouseCursor resizeLeftRight = SystemMouseCursor._(kind: 'resizeLeftRight'); |
724 | |
725 | /// A cursor indicating resizing an object bidirectionally from its top or |
726 | /// bottom edge. |
727 | /// |
728 | /// Typically the shape of a bidirectional arrow pointing up and down. |
729 | /// |
730 | /// Corresponds to: |
731 | /// |
732 | /// * Android: TYPE_VERTICAL_DOUBLE_ARROW |
733 | /// * Web: ns-resize |
734 | /// * Windows: IDC_SIZENS |
735 | /// * Windows UWP: CoreCursorType::SizeNorthSouth |
736 | /// * Linux: ns-resize |
737 | /// * macOS: resizeUpDownCursor |
738 | static const SystemMouseCursor resizeUpDown = SystemMouseCursor._(kind: 'resizeUpDown'); |
739 | |
740 | /// A cursor indicating resizing an object bidirectionally from its top left or |
741 | /// bottom right corner. |
742 | /// |
743 | /// Typically the shape of a bidirectional arrow pointing upper left and lower right. |
744 | /// |
745 | /// Corresponds to: |
746 | /// |
747 | /// * Android: TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW |
748 | /// * Web: nwse-resize |
749 | /// * Windows: IDC_SIZENWSE |
750 | /// * Windows UWP: CoreCursorType::SizeNorthwestSoutheast |
751 | /// * Linux: nwse-resize |
752 | static const SystemMouseCursor resizeUpLeftDownRight = SystemMouseCursor._(kind: 'resizeUpLeftDownRight'); |
753 | |
754 | /// A cursor indicating resizing an object bidirectionally from its top right or |
755 | /// bottom left corner. |
756 | /// |
757 | /// Typically the shape of a bidirectional arrow pointing upper right and lower left. |
758 | /// |
759 | /// Corresponds to: |
760 | /// |
761 | /// * Android: TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW |
762 | /// * Windows: IDC_SIZENESW |
763 | /// * Windows UWP: CoreCursorType::SizeNortheastSouthwest |
764 | /// * Web: nesw-resize |
765 | /// * Linux: nesw-resize |
766 | static const SystemMouseCursor resizeUpRightDownLeft = SystemMouseCursor._(kind: 'resizeUpRightDownLeft'); |
767 | |
768 | /// A cursor indicating resizing an object from its top edge. |
769 | /// |
770 | /// Typically the shape of an arrow pointing up. May fallback to [resizeUpDown]. |
771 | /// |
772 | /// Corresponds to: |
773 | /// |
774 | /// * Android: TYPE_VERTICAL_DOUBLE_ARROW |
775 | /// * Web: n-resize |
776 | /// * Windows: IDC_SIZENS |
777 | /// * Windows UWP: CoreCursorType::SizeNorthSouth |
778 | /// * Linux: n-resize |
779 | /// * macOS: resizeUpCursor |
780 | static const SystemMouseCursor resizeUp = SystemMouseCursor._(kind: 'resizeUp'); |
781 | |
782 | /// A cursor indicating resizing an object from its bottom edge. |
783 | /// |
784 | /// Typically the shape of an arrow pointing down. May fallback to [resizeUpDown]. |
785 | /// |
786 | /// Corresponds to: |
787 | /// |
788 | /// * Android: TYPE_VERTICAL_DOUBLE_ARROW |
789 | /// * Web: s-resize |
790 | /// * Windows: IDC_SIZENS |
791 | /// * Windows UWP: CoreCursorType::SizeNorthSouth |
792 | /// * Linux: s-resize |
793 | /// * macOS: resizeDownCursor |
794 | static const SystemMouseCursor resizeDown = SystemMouseCursor._(kind: 'resizeDown'); |
795 | |
796 | /// A cursor indicating resizing an object from its left edge. |
797 | /// |
798 | /// Typically the shape of an arrow pointing left. May fallback to [resizeLeftRight]. |
799 | /// |
800 | /// Corresponds to: |
801 | /// |
802 | /// * Android: TYPE_HORIZONTAL_DOUBLE_ARROW |
803 | /// * Web: w-resize |
804 | /// * Windows: IDC_SIZEWE |
805 | /// * Windows UWP: CoreCursorType::SizeWestEast |
806 | /// * Linux: w-resize |
807 | /// * macOS: resizeLeftCursor |
808 | static const SystemMouseCursor resizeLeft = SystemMouseCursor._(kind: 'resizeLeft'); |
809 | |
810 | /// A cursor indicating resizing an object from its right edge. |
811 | /// |
812 | /// Typically the shape of an arrow pointing right. May fallback to [resizeLeftRight]. |
813 | /// |
814 | /// Corresponds to: |
815 | /// |
816 | /// * Android: TYPE_HORIZONTAL_DOUBLE_ARROW |
817 | /// * Web: e-resize |
818 | /// * Windows: IDC_SIZEWE |
819 | /// * Windows UWP: CoreCursorType::SizeWestEast |
820 | /// * Linux: e-resize |
821 | /// * macOS: resizeRightCursor |
822 | static const SystemMouseCursor resizeRight = SystemMouseCursor._(kind: 'resizeRight'); |
823 | |
824 | /// A cursor indicating resizing an object from its top-left corner. |
825 | /// |
826 | /// Typically the shape of an arrow pointing upper left. May fallback to [resizeUpLeftDownRight]. |
827 | /// |
828 | /// Corresponds to: |
829 | /// |
830 | /// * Android: TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW |
831 | /// * Web: nw-resize |
832 | /// * Windows: IDC_SIZENWSE |
833 | /// * Windows UWP: CoreCursorType::SizeNorthwestSoutheast |
834 | /// * Linux: nw-resize |
835 | static const SystemMouseCursor resizeUpLeft = SystemMouseCursor._(kind: 'resizeUpLeft'); |
836 | |
837 | /// A cursor indicating resizing an object from its top-right corner. |
838 | /// |
839 | /// Typically the shape of an arrow pointing upper right. May fallback to [resizeUpRightDownLeft]. |
840 | /// |
841 | /// Corresponds to: |
842 | /// |
843 | /// * Android: TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW |
844 | /// * Web: ne-resize |
845 | /// * Windows: IDC_SIZENESW |
846 | /// * Windows UWP: CoreCursorType::SizeNortheastSouthwest |
847 | /// * Linux: ne-resize |
848 | static const SystemMouseCursor resizeUpRight = SystemMouseCursor._(kind: 'resizeUpRight'); |
849 | |
850 | /// A cursor indicating resizing an object from its bottom-left corner. |
851 | /// |
852 | /// Typically the shape of an arrow pointing lower left. May fallback to [resizeUpRightDownLeft]. |
853 | /// |
854 | /// Corresponds to: |
855 | /// |
856 | /// * Android: TYPE_TOP_RIGHT_DIAGONAL_DOUBLE_ARROW |
857 | /// * Web: sw-resize |
858 | /// * Windows: IDC_SIZENESW |
859 | /// * Windows UWP: CoreCursorType::SizeNortheastSouthwest |
860 | /// * Linux: sw-resize |
861 | static const SystemMouseCursor resizeDownLeft = SystemMouseCursor._(kind: 'resizeDownLeft'); |
862 | |
863 | /// A cursor indicating resizing an object from its bottom-right corner. |
864 | /// |
865 | /// Typically the shape of an arrow pointing lower right. May fallback to [resizeUpLeftDownRight]. |
866 | /// |
867 | /// Corresponds to: |
868 | /// |
869 | /// * Android: TYPE_TOP_LEFT_DIAGONAL_DOUBLE_ARROW |
870 | /// * Web: se-resize |
871 | /// * Windows: IDC_SIZENWSE |
872 | /// * Windows UWP: CoreCursorType::SizeNorthwestSoutheast |
873 | /// * Linux: se-resize |
874 | static const SystemMouseCursor resizeDownRight = SystemMouseCursor._(kind: 'resizeDownRight'); |
875 | |
876 | /// A cursor indicating resizing a column, or an item horizontally. |
877 | /// |
878 | /// Typically the shape of arrows pointing left and right with a vertical bar |
879 | /// separating them. May fallback to [resizeLeftRight]. |
880 | /// |
881 | /// Corresponds to: |
882 | /// |
883 | /// * Android: TYPE_HORIZONTAL_DOUBLE_ARROW |
884 | /// * Web: col-resize |
885 | /// * Windows: IDC_SIZEWE |
886 | /// * Windows UWP: CoreCursorType::SizeWestEast |
887 | /// * Linux: col-resize |
888 | /// * macOS: resizeLeftRightCursor |
889 | static const SystemMouseCursor resizeColumn = SystemMouseCursor._(kind: 'resizeColumn'); |
890 | |
891 | /// A cursor indicating resizing a row, or an item vertically. |
892 | /// |
893 | /// Typically the shape of arrows pointing up and down with a horizontal bar |
894 | /// separating them. May fallback to [resizeUpDown]. |
895 | /// |
896 | /// Corresponds to: |
897 | /// |
898 | /// * Android: TYPE_VERTICAL_DOUBLE_ARROW |
899 | /// * Web: row-resize |
900 | /// * Windows: IDC_SIZENS |
901 | /// * Windows UWP: CoreCursorType::SizeNorthSouth |
902 | /// * Linux: row-resize |
903 | /// * macOS: resizeUpDownCursor |
904 | static const SystemMouseCursor resizeRow = SystemMouseCursor._(kind: 'resizeRow'); |
905 | |
906 | |
907 | // OTHER OPERATIONS |
908 | |
909 | /// A cursor indicating zooming in. |
910 | /// |
911 | /// Typically a magnifying glass with a plus sign. |
912 | /// |
913 | /// Corresponds to: |
914 | /// |
915 | /// * Android: TYPE_ZOOM_IN |
916 | /// * Web: zoom-in |
917 | /// * Linux: zoom-in |
918 | static const SystemMouseCursor zoomIn = SystemMouseCursor._(kind: 'zoomIn'); |
919 | |
920 | /// A cursor indicating zooming out. |
921 | /// |
922 | /// Typically a magnifying glass with a minus sign. |
923 | /// |
924 | /// Corresponds to: |
925 | /// |
926 | /// * Android: TYPE_ZOOM_OUT |
927 | /// * Web: zoom-out |
928 | /// * Linux: zoom-out |
929 | static const SystemMouseCursor zoomOut = SystemMouseCursor._(kind: 'zoomOut'); |
930 | } |
931 |
Definitions
- MouseCursorManager
- MouseCursorManager
- debugDeviceActiveCursor
- handleDeviceCursorUpdate
- MouseCursorSession
- MouseCursorSession
- activate
- dispose
- MouseCursor
- MouseCursor
- createSession
- debugDescription
- toString
- _DeferringMouseCursor
- _
- createSession
- debugDescription
- firstNonDeferred
- _NoopMouseCursorSession
- _NoopMouseCursorSession
- activate
- dispose
- _NoopMouseCursor
- _
- createSession
- debugDescription
- _SystemMouseCursorSession
- _SystemMouseCursorSession
- cursor
- activate
- dispose
- SystemMouseCursor
- _
- debugDescription
- createSession
- ==
- hashCode
- debugFillProperties
Learn more about Flutter for embedded and desktop on industrialflutter.com