edge_dims.dart 4.34 KB
Newer Older
1 2 3 4 5
// 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.

import 'dart:ui' as ui;
6
import 'dart:ui' show hashValues;
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45

/// An immutable set of offsets in each of the four cardinal directions.
///
/// Typically used for an offset from each of the four sides of a box. For
/// example, the padding inside a box can be represented using this class.
class EdgeDims {
  /// Constructs an EdgeDims from offsets from the top, right, bottom and left.
  const EdgeDims.TRBL(this.top, this.right, this.bottom, this.left);

  /// Constructs an EdgeDims where all the offsets are value.
  const EdgeDims.all(double value)
      : top = value, right = value, bottom = value, left = value;

  /// Constructs an EdgeDims with only the given values non-zero.
  const EdgeDims.only({ this.top: 0.0,
                        this.right: 0.0,
                        this.bottom: 0.0,
                        this.left: 0.0 });

  /// Constructs an EdgeDims with symmetrical vertical and horizontal offsets.
  const EdgeDims.symmetric({ double vertical: 0.0,
                             double horizontal: 0.0 })
    : top = vertical, left = horizontal, bottom = vertical, right = horizontal;

  /// The offset from the top.
  final double top;

  /// The offset from the right.
  final double right;

  /// The offset from the bottom.
  final double bottom;

  /// The offset from the left.
  final double left;

  /// Whether every dimension is non-negative.
  bool get isNonNegative => top >= 0.0 && right >= 0.0 && bottom >= 0.0 && left >= 0.0;

Adam Barth's avatar
Adam Barth committed
46 47 48 49 50 51 52 53 54 55 56
  /// The total offset in the vertical direction.
  double get horizontal => left + right;

  /// The total offset in the horizontal direction.
  double get vertical => top + bottom;

  /// The size that this EdgeDims would occupy with an empty interior.
  ui.Size get collapsedSize => new ui.Size(horizontal, vertical);

  /// An EdgeDims with top and bottom as well as left and right flipped.
  EdgeDims get flipped => new EdgeDims.TRBL(bottom, left, top, right);
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148

  ui.Rect inflateRect(ui.Rect rect) {
    return new ui.Rect.fromLTRB(rect.left - left, rect.top - top, rect.right + right, rect.bottom + bottom);
  }

  EdgeDims operator -(EdgeDims other) {
    return new EdgeDims.TRBL(
      top - other.top,
      right - other.right,
      bottom - other.bottom,
      left - other.left
    );
  }

  EdgeDims operator +(EdgeDims other) {
    return new EdgeDims.TRBL(
      top + other.top,
      right + other.right,
      bottom + other.bottom,
      left + other.left
    );
  }

  EdgeDims operator *(double other) {
    return new EdgeDims.TRBL(
      top * other,
      right * other,
      bottom * other,
      left * other
    );
  }

  EdgeDims operator /(double other) {
    return new EdgeDims.TRBL(
      top / other,
      right / other,
      bottom / other,
      left / other
    );
  }

  EdgeDims operator ~/(double other) {
    return new EdgeDims.TRBL(
      (top ~/ other).toDouble(),
      (right ~/ other).toDouble(),
      (bottom ~/ other).toDouble(),
      (left ~/ other).toDouble()
    );
  }

  EdgeDims operator %(double other) {
    return new EdgeDims.TRBL(
      top % other,
      right % other,
      bottom % other,
      left % other
    );
  }

  /// Linearly interpolate between two EdgeDims.
  ///
  /// If either is null, this function interpolates from [EdgeDims.zero].
  static EdgeDims lerp(EdgeDims a, EdgeDims b, double t) {
    if (a == null && b == null)
      return null;
    if (a == null)
      return b * t;
    if (b == null)
      return a * (1.0 - t);
    return new EdgeDims.TRBL(
      ui.lerpDouble(a.top, b.top, t),
      ui.lerpDouble(a.right, b.right, t),
      ui.lerpDouble(a.bottom, b.bottom, t),
      ui.lerpDouble(a.left, b.left, t)
    );
  }

  /// An EdgeDims with zero offsets in each direction.
  static const EdgeDims zero = const EdgeDims.TRBL(0.0, 0.0, 0.0, 0.0);

  bool operator ==(dynamic other) {
    if (identical(this, other))
      return true;
    if (other is! EdgeDims)
      return false;
    final EdgeDims typedOther = other;
    return top == typedOther.top &&
           right == typedOther.right &&
           bottom == typedOther.bottom &&
           left == typedOther.left;
  }

149
  int get hashCode => hashValues(top, left, bottom, right);
150 151 152

  String toString() => "EdgeDims($top, $right, $bottom, $left)";
}