icon.dart 2.71 KB
Newer Older
Adam Barth's avatar
Adam Barth committed
1 2 3 4 5 6 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 46 47 48 49 50 51 52 53 54 55 56 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
// 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:sky' as sky;

import 'package:sky/services.dart';
import 'package:sky/src/fn3/basic.dart';
import 'package:sky/src/fn3/theme.dart';
import 'package:sky/src/fn3/framework.dart';

enum IconThemeColor { white, black }

class IconThemeData {
  const IconThemeData({ this.color });
  final IconThemeColor color;
}

class IconTheme extends InheritedWidget {

  IconTheme({
    Key key,
    this.data,
    Widget child
  }) : super(key: key, child: child) {
    assert(data != null);
    assert(child != null);
  }

  final IconThemeData data;

  static IconThemeData of(BuildContext context) {
    IconTheme result = context.inheritedWidgetOfType(IconTheme);
    return result?.data;
  }

  bool updateShouldNotify(IconTheme old) => data != old.data;

}

AssetBundle _initIconBundle() {
  if (rootBundle != null)
    return rootBundle;
  const String _kAssetBase = '/packages/material_design_icons/icons/';
  return new NetworkAssetBundle(Uri.base.resolve(_kAssetBase));
}

final AssetBundle _iconBundle = _initIconBundle();

class Icon extends StatelessComponent {
  Icon({
    Key key,
    this.size,
    this.type: '',
    this.color,
    this.colorFilter
  }) : super(key: key);

  final int size;
  final String type;
  final IconThemeColor color;
  final sky.ColorFilter colorFilter;

  String getColorSuffix(BuildContext context) {
    IconThemeColor iconThemeColor = color;
    if (iconThemeColor == null) {
      IconThemeData iconThemeData = IconTheme.of(context);
      iconThemeColor = iconThemeData == null ? null : iconThemeData.color;
    }
    if (iconThemeColor == null) {
      ThemeBrightness themeBrightness = Theme.of(context).brightness;
      iconThemeColor = themeBrightness == ThemeBrightness.dark ? IconThemeColor.white : IconThemeColor.black;
    }
    switch(iconThemeColor) {
      case IconThemeColor.white:
        return "white";
      case IconThemeColor.black:
        return "black";
    }
  }

  Widget build(BuildContext context) {
    String category = '';
    String subtype = '';
    List<String> parts = type.split('/');
    if (parts.length == 2) {
      category = parts[0];
      subtype = parts[1];
    }
    // TODO(eseidel): This clearly isn't correct.  Not sure what would be.
    // Should we use the ios images on ios?
    String density = 'drawable-xxhdpi';
    String colorSuffix = getColorSuffix(context);
    return new AssetImage(
      bundle: _iconBundle,
      name: '${category}/${density}/ic_${subtype}_${colorSuffix}_${size}dp.png',
      width: size.toDouble(),
      height: size.toDouble(),
      colorFilter: colorFilter
    );
  }
}