window.dart 19.4 KB
Newer Older
A
Adam Barth 已提交
1 2 3 4
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

A
Adam Barth 已提交
5
part of dart.ui;
A
Adam Barth 已提交
6

I
Ian Hickson 已提交
7
/// Signature of callbacks that have no arguments and return no data.
A
Adam Barth 已提交
8
typedef void VoidCallback();
I
Ian Hickson 已提交
9 10 11 12

/// Signature for [Window.onBeginFrame].
typedef void FrameCallback(Duration duration);

13 14 15
/// Signature for [Window.onPointerDataPacket].
typedef void PointerDataPacketCallback(PointerDataPacket packet);

16 17 18
/// Signature for [Window.onSemanticsAction].
typedef void SemanticsActionCallback(int id, SemanticsAction action);

A
Adam Barth 已提交
19 20 21 22
/// Signature for responses to platform messages.
///
/// Used as a parameter to [Window.sendPlatformMessage] and
/// [Window.onPlatformMessage].
23 24
typedef void PlatformMessageResponseCallback(ByteData data);

A
Adam Barth 已提交
25 26 27
/// Signature for [Window.onPlatformMessage].
typedef void PlatformMessageCallback(String name, ByteData data, PlatformMessageResponseCallback callback);

28
/// States that an application can be in.
29 30 31 32 33 34
///
/// The values below describe notifications from the operating system.
/// Applications should not expect to always receive all possible
/// notifications. For example, if the users pulls out the battery from the
/// device, no notification will be sent before the application is suddenly
/// terminated, along with the rest of the operating system.
35 36 37 38 39
///
/// See also:
///
///  * [WidgetsBindingObserver], for a mechanism to observe the lifecycle state
///    from the widgets layer.
40
enum AppLifecycleState {
41 42 43 44 45
  /// The application is visible and responding to user input.
  resumed,

  /// The application is in an inactive state and is not receiving user input.
  ///
46 47 48 49 50 51
  /// On iOS, this state corresponds to an app or the Flutter host view running
  /// in the foreground inactive state. Apps transition to this state when in
  /// a phone call, responding to a TouchID request, when entering the app
  /// switcher or the control center, or when the UIViewController hosting the
  /// Flutter app is transitioning. Apps in this state should assume that they
  /// may be [paused] at any time.
52 53 54 55 56 57 58 59
  ///
  /// On Android, this state is currently unused.
  inactive,

  /// The application is not currently visible to the user, not responding to
  /// user input, and running in the background.
  ///
  /// When the application is in this state, the engine will not call the
I
Ian Hickson 已提交
60
  /// [Window.onBeginFrame] and [Window.onDrawFrame] callbacks.
61
  ///
62 63
  /// Android apps in this state should assume that they may enter the
  /// [suspending] state at any time.
64
  paused,
65

66 67 68 69 70 71 72
  /// The application will be suspended momentarily.
  ///
  /// When the application is in this state, the engine will not call the
  /// [Window.onBeginFrame] and [Window.onDrawFrame] callbacks.
  ///
  /// On iOS, this state is currently unused.
  suspending,
73
}
A
Adam Barth 已提交
74

75 76 77 78 79
/// A representation of distances for each of the four edges of a rectangle,
/// used to encode the padding that applications should place around their user
/// interface, as exposed by [Window.padding].
///
/// For a generic class that represents distances around a rectangle, see the
I
Ian Hickson 已提交
80
/// [EdgeInsets] class.
81 82 83 84 85 86 87 88
///
/// See also:
///
///  * [WidgetsBindingObserver], for a widgets layer mechanism to receive
///    notifications when the padding changes.
///  * [MediaQuery.of], a simpler mechanism for the same.
///  * [Scaffold], which automatically applies the padding in material design
///    applications.
89
class WindowPadding {
90
  const WindowPadding._({ this.left, this.top, this.right, this.bottom });
A
Adam Barth 已提交
91

A
Adam Barth 已提交
92
  /// The distance from the left edge to the first unobscured pixel, in physical pixels.
93
  final double left;
A
Adam Barth 已提交
94 95

  /// The distance from the top edge to the first unobscured pixel, in physical pixels.
A
Adam Barth 已提交
96
  final double top;
A
Adam Barth 已提交
97 98

  /// The distance from the right edge to the first unobscured pixel, in physical pixels.
A
Adam Barth 已提交
99
  final double right;
A
Adam Barth 已提交
100 101

  /// The distance from the bottom edge to the first unobscured pixel, in physical pixels.
A
Adam Barth 已提交
102
  final double bottom;
103

A
Adam Barth 已提交
104
  /// A window padding that has zeros for each edge.
105
  static const WindowPadding zero = const WindowPadding._(left: 0.0, top: 0.0, right: 0.0, bottom: 0.0);
A
Adam Barth 已提交
106 107
}

108 109 110
/// An identifier used to select a user's language and formatting preferences,
/// consisting of a language and a country. This is a subset of locale
/// identifiers as defined by BCP 47.
111 112 113 114 115
///
/// See also:
///
///  * [Window.locale], which specifies the system's currently selected
///    [Locale].
116
class Locale {
H
Hixie 已提交
117 118 119 120 121
  /// Creates a new Locale object. The first argument is the
  /// primary language subtag, the second is the region subtag.
  ///
  /// For example:
  ///
122 123 124 125
  /// ```dart
  /// const Locale swissFrench = const Locale('fr', 'CH');
  /// const Locale canadianFrench = const Locale('fr', 'CA');
  /// ```
126
  const Locale(this.languageCode, this.countryCode);
127

128
  /// The primary language subtag for the locale.
129
  final String languageCode;
130 131

  /// The region subtag for the locale.
132 133
  final String countryCode;

134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
  bool operator ==(dynamic other) {
    if (identical(this, other))
      return true;
    if (other is! Locale)
      return false;
    final Locale typedOther = other;
    return languageCode == typedOther.languageCode
        && countryCode == typedOther.countryCode;
  }

  int get hashCode {
    int result = 373;
    result = 37 * result + languageCode.hashCode;
    result = 37 * result + countryCode.hashCode;
    return result;
  }

151 152 153
  String toString() => '${languageCode}_$countryCode';
}

154
/// The most basic interface to the host operating system's user interface.
H
Hixie 已提交
155 156 157
///
/// There is a single Window instance in the system, which you can
/// obtain from the [window] property.
A
Adam Barth 已提交
158 159 160
class Window {
  Window._();

161 162 163
  /// The number of device pixels for each logical pixel. This number might not
  /// be a power of two. Indeed, it might not even be an integer. For example,
  /// the Nexus 6 has a device pixel ratio of 3.5.
164 165 166 167 168 169 170 171 172 173
  ///
  /// Device pixels are also referred to as physical pixels. Logical pixels are
  /// also referred to as device-independent or resolution-independent pixels.
  ///
  /// By definition, there are roughly 38 logical pixels per centimeter, or
  /// about 96 logical pixels per inch, of the physical display. The value
  /// returned by [devicePixelRatio] is ultimately obtained either from the
  /// hardware itself, the device drivers, or a hard-coded value stored in the
  /// operating system or firmware, and may be inaccurate, sometimes by a
  /// significant margin.
174 175 176 177 178 179 180 181
  ///
  /// The Flutter framework operates in logical pixels, so it is rarely
  /// necessary to directly deal with this property.
  ///
  /// See also:
  ///
  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
  ///    observe when this value changes.
A
Adam Barth 已提交
182
  double get devicePixelRatio => _devicePixelRatio;
183
  double _devicePixelRatio = 1.0;
A
Adam Barth 已提交
184

185
  /// The dimensions of the rectangle into which the application will be drawn,
A
Adam Barth 已提交
186
  /// in physical pixels.
187 188 189 190 191
  ///
  /// See also:
  ///
  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
  ///    observe when this value changes.
A
Adam Barth 已提交
192 193 194 195 196 197 198 199
  Size get physicalSize => _physicalSize;
  Size _physicalSize = Size.zero;

  /// The number of physical pixels on each side of the display rectangle into
  /// which the application can render, but over which the operating system will
  /// likely place system UI (such as the Android system notification area), or
  /// which might be rendered outside of the physical display (e.g. overscan
  /// regions on television screens).
200 201 202 203 204 205 206 207
  ///
  /// See also:
  ///
  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
  ///    observe when this value changes.
  ///  * [MediaQuery.of], a simpler mechanism for the same.
  ///  * [Scaffold], which automatically applies the padding in material design
  ///    applications.
208
  WindowPadding get padding => _padding;
209
  WindowPadding _padding = WindowPadding.zero;
A
Adam Barth 已提交
210

A
Adam Barth 已提交
211
  /// A callback that is invoked whenever the [devicePixelRatio],
212 213 214
  /// [physicalSize], or [padding] values change, for example when the device is
  /// rotated or when the application is resized (e.g. when showing applications
  /// side-by-side on Android).
Y
Yegor 已提交
215 216 217 218 219 220 221 222 223 224
  ///
  /// The framework invokes this callback in the same zone in which the
  /// callback was set.
  VoidCallback get onMetricsChanged => _onMetricsChanged;
  VoidCallback _onMetricsChanged;
  Zone _onMetricsChangedZone;
  set onMetricsChanged(VoidCallback callback) {
    _onMetricsChanged = callback;
    _onMetricsChangedZone = Zone.current;
  }
225

226 227 228 229 230 231
  /// The system-reported locale.
  ///
  /// This establishes the language and formatting conventions that application
  /// should, if possible, use to render their user interface.
  ///
  /// The [onLocaleChanged] callback is called whenever this value changes.
232 233 234 235 236
  ///
  /// See also:
  ///
  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
  ///    observe when this value changes.
237 238 239
  Locale get locale => _locale;
  Locale _locale;

240
  /// A callback that is invoked whenever [locale] changes value.
241
  ///
Y
Yegor 已提交
242 243 244
  /// The framework invokes this callback in the same zone in which the
  /// callback was set.
  ///
245 246 247 248
  /// See also:
  ///
  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
  ///    observe when this callback is invoked.
Y
Yegor 已提交
249 250 251 252 253 254 255
  VoidCallback get onLocaleChanged => _onLocaleChanged;
  VoidCallback _onLocaleChanged;
  Zone _onLocaleChangedZone;
  set onLocaleChanged(VoidCallback callback) {
    _onLocaleChanged = callback;
    _onLocaleChangedZone = Zone.current;
  }
256

257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
  /// The system-reported text scale.
  ///
  /// This establishes the text scaling factor to use when rendering text,
  /// according to the user's platform preferences.
  ///
  /// The [onTextScaleFactorChanged] callback is called whenever this value
  /// changes.
  ///
  /// See also:
  ///
  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
  ///    observe when this value changes.
  double get textScaleFactor => _textScaleFactor;
  double _textScaleFactor = 1.0;

272 273 274 275 276 277 278
  /// The setting indicating whether time should always be shown in the 24-hour
  /// format.
  /// 
  /// This option is used by [showTimePicker].
  bool get alwaysUse24HourFormat => _alwaysUse24HourFormat;
  bool _alwaysUse24HourFormat = false;

279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
  /// A callback that is invoked whenever [textScaleFactor] changes value.
  ///
  /// The framework invokes this callback in the same zone in which the
  /// callback was set.
  ///
  /// See also:
  ///
  ///  * [WidgetsBindingObserver], for a mechanism at the widgets layer to
  ///    observe when this callback is invoked.
  VoidCallback get onTextScaleFactorChanged => _onTextScaleFactorChanged;
  VoidCallback _onTextScaleFactorChanged;
  Zone _onTextScaleFactorChangedZone;
  set onTextScaleFactorChanged(VoidCallback callback) {
    _onTextScaleFactorChanged = callback;
    _onTextScaleFactorChangedZone = Zone.current;
  }

296 297
  /// A callback that is invoked to notify the application that it is an
  /// appropriate time to provide a scene using the [SceneBuilder] API and the
A
Adam Barth 已提交
298 299
  /// [render] method. When possible, this is driven by the hardware VSync
  /// signal. This is only called if [scheduleFrame] has been called since the
300
  /// last time this callback was invoked.
I
Ian Hickson 已提交
301 302 303 304
  ///
  /// The [onDrawFrame] callback is invoked immediately after [onBeginFrame],
  /// after draining any microtasks (e.g. completions of any [Future]s) queued
  /// by the [onBeginFrame] handler.
305
  ///
Y
Yegor 已提交
306 307 308
  /// The framework invokes this callback in the same zone in which the
  /// callback was set.
  ///
309 310 311 312 313 314
  /// See also:
  ///
  ///  * [SchedulerBinding], the Flutter framework class which manages the
  ///    scheduling of frames.
  ///  * [RendererBinding], the Flutter framework class which manages layout and
  ///    painting.
Y
Yegor 已提交
315 316 317 318 319 320 321
  FrameCallback get onBeginFrame => _onBeginFrame;
  FrameCallback _onBeginFrame;
  Zone _onBeginFrameZone;
  set onBeginFrame(FrameCallback callback) {
    _onBeginFrame = callback;
    _onBeginFrameZone = Zone.current;
  }
322

I
Ian Hickson 已提交
323 324
  /// A callback that is invoked for each frame after [onBeginFrame] has
  /// completed and after the microtask queue has been drained. This can be
325
  /// used to implement a second phase of frame rendering that happens
I
Ian Hickson 已提交
326
  /// after any deferred work queued by the [onBeginFrame] phase.
327
  ///
Y
Yegor 已提交
328 329 330
  /// The framework invokes this callback in the same zone in which the
  /// callback was set.
  ///
331 332 333 334 335 336
  /// See also:
  ///
  ///  * [SchedulerBinding], the Flutter framework class which manages the
  ///    scheduling of frames.
  ///  * [RendererBinding], the Flutter framework class which manages layout and
  ///    painting.
Y
Yegor 已提交
337 338 339 340 341 342 343
  VoidCallback get onDrawFrame => _onDrawFrame;
  VoidCallback _onDrawFrame;
  Zone _onDrawFrameZone;
  set onDrawFrame(VoidCallback callback) {
    _onDrawFrame = callback;
    _onDrawFrameZone = Zone.current;
  }
344

345
  /// A callback that is invoked when pointer data is available.
346
  ///
Y
Yegor 已提交
347 348 349
  /// The framework invokes this callback in the same zone in which the
  /// callback was set.
  ///
350 351 352 353
  /// See also:
  ///
  ///  * [GestureBinding], the Flutter framework class which manages pointer
  ///    events.
Y
Yegor 已提交
354 355 356 357 358 359 360
  PointerDataPacketCallback get onPointerDataPacket => _onPointerDataPacket;
  PointerDataPacketCallback _onPointerDataPacket;
  Zone _onPointerDataPacketZone;
  set onPointerDataPacket(PointerDataPacketCallback callback) {
    _onPointerDataPacket = callback;
    _onPointerDataPacketZone = Zone.current;
  }
361

362 363
  /// The route or path that the operating system requested when the application
  /// was launched.
364 365
  String get defaultRouteName => _defaultRouteName();
  String _defaultRouteName() native "Window_defaultRouteName";
366 367

  /// Requests that, at the next appropriate opportunity, the [onBeginFrame]
I
Ian Hickson 已提交
368
  /// and [onDrawFrame] callbacks be invoked.
369 370 371 372 373
  ///
  /// See also:
  ///
  ///  * [SchedulerBinding], the Flutter framework class which manages the
  ///    scheduling of frames.
A
Adam Barth 已提交
374
  void scheduleFrame() native "Window_scheduleFrame";
375 376

  /// Updates the application's rendering on the GPU with the newly provided
377
  /// [Scene]. This function must be called within the scope of the
I
Ian Hickson 已提交
378 379 380 381
  /// [onBeginFrame] or [onDrawFrame] callbacks being invoked. If this function
  /// is called a second time during a single [onBeginFrame]/[onDrawFrame]
  /// callback sequence or called outside the scope of those callbacks, the call
  /// will be ignored.
H
Hixie 已提交
382
  ///
I
Ian Hickson 已提交
383 384 385 386 387
  /// To record graphical operations, first create a [PictureRecorder], then
  /// construct a [Canvas], passing that [PictureRecorder] to its constructor.
  /// After issuing all the graphical operations, call the
  /// [PictureRecorder.endRecording] function on the [PictureRecorder] to obtain
  /// the final [Picture] that represents the issued graphical operations.
388
  ///
H
Hixie 已提交
389
  /// Next, create a [SceneBuilder], and add the [Picture] to it using
I
Ian Hickson 已提交
390 391 392
  /// [SceneBuilder.addPicture]. With the [SceneBuilder.build] method you can
  /// then obtain a [Scene] object, which you can display to the user via this
  /// [render] function.
393 394 395 396 397 398 399
  ///
  /// See also:
  ///
  ///  * [SchedulerBinding], the Flutter framework class which manages the
  ///    scheduling of frames.
  ///  * [RendererBinding], the Flutter framework class which manages layout and
  ///    painting.
400
  void render(Scene scene) native "Window_render";
401 402 403 404 405 406 407 408 409 410

  /// Whether the user has requested that [updateSemantics] be called when
  /// the semantic contents of window changes.
  ///
  /// The [onSemanticsEnabledChanged] callback is called whenever this value
  /// changes.
  bool get semanticsEnabled => _semanticsEnabled;
  bool _semanticsEnabled = false;

  /// A callback that is invoked when the value of [semanticsEnabled] changes.
Y
Yegor 已提交
411 412 413 414 415 416 417 418 419 420
  ///
  /// The framework invokes this callback in the same zone in which the
  /// callback was set.
  VoidCallback get onSemanticsEnabledChanged => _onSemanticsEnabledChanged;
  VoidCallback _onSemanticsEnabledChanged;
  Zone _onSemanticsEnabledChangedZone;
  set onSemanticsEnabledChanged(VoidCallback callback) {
    _onSemanticsEnabledChanged = callback;
    _onSemanticsEnabledChangedZone = Zone.current;
  }
421 422 423 424 425 426

  /// A callback that is invoked whenever the user requests an action to be
  /// performed.
  ///
  /// This callback is used when the user expresses the action they wish to
  /// perform based on the semantics supplied by [updateSemantics].
Y
Yegor 已提交
427 428 429 430 431 432 433 434 435 436
  ///
  /// The framework invokes this callback in the same zone in which the
  /// callback was set.
  SemanticsActionCallback get onSemanticsAction => _onSemanticsAction;
  SemanticsActionCallback _onSemanticsAction;
  Zone _onSemanticsActionZone;
  set onSemanticsAction(SemanticsActionCallback callback) {
    _onSemanticsAction = callback;
    _onSemanticsActionZone = Zone.current;
  }
437 438 439 440 441 442 443 444 445

  /// Change the retained semantics data about this window.
  ///
  /// If [semanticsEnabled] is true, the user has requested that this funciton
  /// be called whenever the semantic content of this window changes.
  ///
  /// In either case, this function disposes the given update, which means the
  /// semantics update cannot be used further.
  void updateSemantics(SemanticsUpdate update) native "Window_updateSemantics";
446

A
Adam Barth 已提交
447 448 449 450 451 452
  /// Sends a message to a platform-specific plugin.
  ///
  /// The `name` parameter determines which plugin receives the message. The
  /// `data` parameter contains the message payload and is typically UTF-8
  /// encoded JSON but can be arbitrary data. If the plugin replies to the
  /// message, `callback` will be called with the response.
Y
Yegor 已提交
453 454 455
  ///
  /// The framework invokes [callback] in the same zone in which this method
  /// was called.
A
Adam Barth 已提交
456 457 458
  void sendPlatformMessage(String name,
                           ByteData data,
                           PlatformMessageResponseCallback callback) {
Y
Yegor 已提交
459
    _sendPlatformMessage(name, _zonedPlatformMessageResponseCallback(callback), data);
460
  }
A
Adam Barth 已提交
461 462 463
  void _sendPlatformMessage(String name,
                            PlatformMessageResponseCallback callback,
                            ByteData data) native "Window_sendPlatformMessage";
464

A
Adam Barth 已提交
465 466 467 468 469 470 471 472
  /// Called whenever this window receives a message from a platform-specific
  /// plugin.
  ///
  /// The `name` parameter determines which plugin sent the message. The `data`
  /// parameter is the payload and is typically UTF-8 encoded JSON but can be
  /// arbitrary data.
  ///
  /// Message handlers must call the function given in the `callback` parameter.
473
  /// If the handler does not need to respond, the handler should pass null to
A
Adam Barth 已提交
474
  /// the callback.
Y
Yegor 已提交
475 476 477 478 479 480 481 482 483 484
  ///
  /// The framework invokes this callback in the same zone in which the
  /// callback was set.
  PlatformMessageCallback get onPlatformMessage => _onPlatformMessage;
  PlatformMessageCallback _onPlatformMessage;
  Zone _onPlatformMessageZone;
  set onPlatformMessage(PlatformMessageCallback callback) {
    _onPlatformMessage = callback;
    _onPlatformMessageZone = Zone.current;
  }
A
Adam Barth 已提交
485 486 487 488

  /// Called by [_dispatchPlatformMessage].
  void _respondToPlatformMessage(int responseId, ByteData data)
      native "Window_respondToPlatformMessage";
Y
Yegor 已提交
489 490 491 492 493 494 495 496 497 498 499 500 501 502

  /// Wraps the given [callback] in another callback that ensures that the
  /// original callback is called in the zone it was registered in.
  static PlatformMessageResponseCallback _zonedPlatformMessageResponseCallback(PlatformMessageResponseCallback callback) {
    if (callback == null)
      return null;

    // Store the zone in which the callback is being registered.
    final Zone registrationZone = Zone.current;

    return (ByteData data) {
      registrationZone.runUnaryGuarded(callback, data);
    };
  }
A
Adam Barth 已提交
503 504
}

I
Ian Hickson 已提交
505 506 507
/// The [Window] singleton. This object exposes the size of the display, the
/// core scheduler API, the input event callback, the graphics drawing API, and
/// other such core services.
A
Adam Barth 已提交
508
final Window window = new Window._();