debug.dart 6.58 KB
Newer Older
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.

5
import 'package:flutter/foundation.dart';
6
import 'package:flutter/painting.dart';
7

8
export 'package:flutter/foundation.dart' show debugPrint;
9

10 11 12
// Any changes to this file should be reflected in the debugAssertAllRenderVarsUnset()
// function below.

13
const HSVColor _kDebugDefaultRepaintColor = const HSVColor.fromAHSV(0.4, 60.0, 1.0, 1.0);
14

15
/// Causes each RenderBox to paint a box around its bounds, and some extra
Ian Hickson's avatar
Ian Hickson committed
16
/// boxes, such as [RenderPadding], to draw construction lines.
17
///
18
/// The edges of the boxes are painted as a one-pixel-thick `const Color(0xFF00FFFF)` outline.
19
///
20
/// Spacing is painted as a solid `const Color(0x90909090)` area.
21
///
22 23 24
/// Padding is filled in solid `const Color(0x900090FF)`, with the inner edge
/// outlined in `const Color(0xFF0090FF)`, using [debugPaintPadding].
bool debugPaintSizeEnabled = false;
25

Adam Barth's avatar
Adam Barth committed
26
/// Causes each RenderBox to paint a line at each of its baselines.
27
bool debugPaintBaselinesEnabled = false;
Adam Barth's avatar
Adam Barth committed
28 29

/// Causes each Layer to paint a box around its bounds.
30
bool debugPaintLayerBordersEnabled = false;
Adam Barth's avatar
Adam Barth committed
31

32 33 34 35 36 37
/// Causes objects like [RenderPointerListener] to flash while they are being
/// tapped. This can be useful to see how large the hit box is, e.g. when
/// debugging buttons that are harder to hit than expected.
///
/// For details on how to support this in your [RenderBox] subclass, see
/// [RenderBox.debugHandleEvent].
38
bool debugPaintPointersEnabled = false;
39

40
/// Overlay a rotating set of colors when repainting layers in checked mode.
41
bool debugRepaintRainbowEnabled = false;
42

43 44 45
/// Overlay a rotating set of colors when repainting text in checked mode.
bool debugRepaintTextRainbowEnabled = false;

46
/// The current color to overlay when repainting a layer.
47 48 49 50 51 52 53
///
/// This is used by painting debug code that implements
/// [debugRepaintRainbowEnabled] or [debugRepaintTextRainbowEnabled].
///
/// The value is incremented by [RenderView.compositeFrame] if either of those
/// flags is enabled.
HSVColor debugCurrentRepaintColor = _kDebugDefaultRepaintColor;
54

55
/// Log the call stacks that mark render objects as needing layout.
56 57 58 59 60
///
/// For sanity, this only logs the stack traces of cases where an object is
/// added to the list of nodes needing layout. This avoids printing multiple
/// redundant stack traces as a single [RenderObject.markNeedsLayout] call walks
/// up the tree.
61 62
bool debugPrintMarkNeedsLayoutStacks = false;

63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85
/// Log the call stacks that mark render objects as needing paint.
bool debugPrintMarkNeedsPaintStacks = false;

/// Log the dirty render objects that are laid out each frame.
///
/// Combined with [debugPrintBeginFrameBanner], this allows you to distinguish
/// layouts triggered by the initial mounting of a render tree (e.g. in a call
/// to [runApp]) from the regular layouts triggered by the pipeline.
///
/// Combined with [debugPrintMarkNeedsLayoutStacks], this lets you watch a
/// render object's dirty/clean lifecycle.
///
/// See also:
///
///  * [debugProfilePaintsEnabled], which does something similar for
///    painting but using the timeline view.
///
///  * [debugPrintRebuildDirtyWidgets], which does something similar for widgets
///    being rebuilt.
///
///  * The discussion at [RendererBinding.drawFrame].
bool debugPrintLayouts = false;

86
/// Check the intrinsic sizes of each [RenderBox] during layout.
87 88 89
///
/// By default this is turned off since these checks are expensive, but it is
/// enabled by the test framework.
90 91
bool debugCheckIntrinsicSizes = false;

92 93 94 95 96
/// Adds [dart:developer.Timeline] events for every [RenderObject] painted.
///
/// This is only enabled in debug builds. The timing information this exposes is
/// not representative of actual paints. However, it can expose unexpected
/// painting in the timeline.
97
///
Ian Hickson's avatar
Ian Hickson committed
98 99 100
/// For details on how to use [dart:developer.Timeline] events in the Dart
/// Observatory to optimize your app, see:
/// <https://fuchsia.googlesource.com/sysui/+/master/docs/performance.md>
101 102 103 104 105 106
///
/// See also:
///
///  * [debugPrintLayouts], which does something similar for layout but using
///    console output.
///
107 108 109
///  * [debugProfileBuildsEnabled], which does something similar for widgets
///    being rebuilt, and [debugPrintRebuildDirtyWidgets], its console
///    equivalent.
110 111
///
///  * The discussion at [RendererBinding.drawFrame].
112 113 114
bool debugProfilePaintsEnabled = false;


115 116 117 118 119 120 121 122 123 124
void _debugDrawDoubleRect(Canvas canvas, Rect outerRect, Rect innerRect, Color color) {
  final Path path = new Path()
    ..fillType = PathFillType.evenOdd
    ..addRect(outerRect)
    ..addRect(innerRect);
  final Paint paint = new Paint()
    ..color = color;
  canvas.drawPath(path, paint);
}

125
/// Paint a diagram showing the given area as padding.
126 127 128 129 130 131
///
/// Called by [RenderPadding.debugPaintSize] when [debugPaintSizeEnabled] is
/// true.
void debugPaintPadding(Canvas canvas, Rect outerRect, Rect innerRect, { double outlineWidth: 2.0 }) {
  assert(() {
    if (innerRect != null && !innerRect.isEmpty) {
132 133
      _debugDrawDoubleRect(canvas, outerRect, innerRect, const Color(0x900090FF));
      _debugDrawDoubleRect(canvas, innerRect.inflate(outlineWidth).intersect(outerRect), innerRect, const Color(0xFF0090FF));
134 135
    } else {
      final Paint paint = new Paint()
136
        ..color = const Color(0x90909090);
137 138 139
      canvas.drawRect(outerRect, paint);
    }
    return true;
140
  }());
141 142
}

143 144 145 146 147
/// Returns true if none of the rendering library debug variables have been changed.
///
/// This function is used by the test framework to ensure that debug variables
/// haven't been inadvertently changed.
///
148
/// See <https://docs.flutter.io/flutter/rendering/rendering-library.html> for
149
/// a complete list.
150 151 152 153 154
///
/// The `debugCheckIntrinsicSizesOverride` argument can be provided to override
/// the expected value for [debugCheckIntrinsicSizes]. (This exists because the
/// test framework itself overrides this value in some cases.)
bool debugAssertAllRenderVarsUnset(String reason, { bool debugCheckIntrinsicSizesOverride: false }) {
155 156 157 158 159 160
  assert(() {
    if (debugPaintSizeEnabled ||
        debugPaintBaselinesEnabled ||
        debugPaintLayerBordersEnabled ||
        debugPaintPointersEnabled ||
        debugRepaintRainbowEnabled ||
161
        debugRepaintTextRainbowEnabled ||
162
        debugCurrentRepaintColor != _kDebugDefaultRepaintColor ||
163
        debugPrintMarkNeedsLayoutStacks ||
164 165
        debugPrintMarkNeedsPaintStacks ||
        debugPrintLayouts ||
166
        debugCheckIntrinsicSizes != debugCheckIntrinsicSizesOverride ||
167
        debugProfilePaintsEnabled) {
168 169 170
      throw new FlutterError(reason);
    }
    return true;
171
  }());
172 173
  return true;
}