stock_arrow.dart 2.61 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
    final Paint paint = Paint()..color = color;
18 19 20
    paint.strokeWidth = 1.0;
    const double padding = 2.0;
    assert(padding > paint.strokeWidth / 2.0); // make sure the circle remains inside the box
21 22 23
    final double r = (size.shortestSide - padding) / 2.0; // radius of the circle
    final double centerX = padding + r;
    final double centerY = padding + r;
24 25

    // Draw the arrow.
26
    const double w = 8.0;
27 28 29 30 31 32 33 34
    double h = 5.0;
    double arrowY;
    if (percentChange < 0.0) {
      h = -h;
      arrowY = centerX + 1.0;
    } else {
      arrowY = centerX - 1.0;
    }
35
    final Path path = Path();
36 37 38 39
    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
    canvas.drawCircle(Offset(centerX, centerY), r, paint);
46 47
  }

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

55
class StockArrow extends StatelessWidget {
56
  const StockArrow({ Key key, this.percentChange }) : super(key: key);
57 58 59 60

  final double percentChange;

  int _colorIndexForPercentChange(double percentChange) {
61
    const double maxPercent = 10.0;
62
    final double normalizedPercentChange = math.min(percentChange.abs(), maxPercent) / maxPercent;
63 64 65 66 67
    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 Container(
75 76
      width: 40.0,
      height: 40.0,
77
      margin: const EdgeInsets.symmetric(horizontal: 5.0),
78 79
      child: CustomPaint(
        painter: StockArrowPainter(
80 81 82 83 84
          // TODO(jackson): This should change colors with the theme
          color: _colorForPercentChange(percentChange),
          percentChange: percentChange
        )
      )
85 86 87
    );
  }
}