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) : 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.
106abstract 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
188abstract 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
249class _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
272class _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.
295class _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
308class _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.
357class 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.
405abstract 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

Provided by KDAB

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