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