stock_arrow.dart 2.57 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 6 7
import 'dart:math' as math;

import 'package:flutter/material.dart';
8

9 10 11 12 13 14
class StockArrowPainter extends CustomPainter {
  StockArrowPainter({ this.color, this.percentChange });

  final Color color;
  final double percentChange;

15
  @override
Adam Barth's avatar
Adam Barth committed
16
  void paint(Canvas canvas, Size size) {
17 18 19 20
    Paint paint = new Paint()..color = color;
    paint.strokeWidth = 1.0;
    const double padding = 2.0;
    assert(padding > paint.strokeWidth / 2.0); // make sure the circle remains inside the box
21
    double r = (size.shortestSide - padding) / 2.0; // radius of the circle
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
    double centerX = padding + r;
    double centerY = padding + r;

    // Draw the arrow.
    double w = 8.0;
    double h = 5.0;
    double arrowY;
    if (percentChange < 0.0) {
      h = -h;
      arrowY = centerX + 1.0;
    } else {
      arrowY = centerX - 1.0;
    }
    Path path = new Path();
    path.moveTo(centerX, arrowY - h); // top of the arrow
    path.lineTo(centerX + w, arrowY + h);
    path.lineTo(centerX - w, arrowY + h);
    path.close();
40
    paint.style = PaintingStyle.fill;
41 42 43
    canvas.drawPath(path, paint);

    // Draw a circle that circumscribes the arrow.
44
    paint.style = PaintingStyle.stroke;
45 46 47
    canvas.drawCircle(new Point(centerX, centerY), r, paint);
  }

48
  @override
49 50 51 52 53 54
  bool shouldRepaint(StockArrowPainter oldPainter) {
    return oldPainter.color != color
        || oldPainter.percentChange != percentChange;
  }
}

55
class StockArrow extends StatelessWidget {
56
  StockArrow({ Key key, this.percentChange }) : super(key: key);
57 58 59 60 61 62 63 64 65 66 67

  final double percentChange;

  int _colorIndexForPercentChange(double percentChange) {
    double maxPercent = 10.0;
    double normalizedPercentChange = math.min(percentChange.abs(), maxPercent) / maxPercent;
    return 100 + (normalizedPercentChange * 8.0).floor() * 100;
  }

  Color _colorForPercentChange(double percentChange) {
    if (percentChange > 0)
68 69
      return Colors.green[_colorIndexForPercentChange(percentChange)];
    return Colors.red[_colorIndexForPercentChange(percentChange)];
70 71
  }

72
  @override
73
  Widget build(BuildContext context) {
74
    return new Container(
75 76
      width: 40.0,
      height: 40.0,
77
      margin: const EdgeInsets.symmetric(horizontal: 5.0),
78 79 80 81 82 83 84
      child: new CustomPaint(
        painter: new StockArrowPainter(
          // TODO(jackson): This should change colors with the theme
          color: _colorForPercentChange(percentChange),
          percentChange: percentChange
        )
      )
85 86 87
    );
  }
}