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';
7library;
8
9import 'package:flutter/foundation.dart';
10import 'package:flutter/gestures.dart';
11
12import 'system_channels.dart';
13
14export 'package:flutter/foundation.dart' show DiagnosticLevel, DiagnosticPropertiesBuilder;
15export '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].
21class 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.
107abstract 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
189abstract 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
250class _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
273class _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.
292class _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
305class _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.
355class 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.
406abstract 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

Provided by KDAB

Privacy Policy
Learn more about Flutter for embedded and desktop on industrialflutter.com