// 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' show Color; import 'colors.dart'; import 'icon_theme_data.dart'; import 'typography.dart'; enum ThemeBrightness { dark, light } class ThemeData { ThemeData({ ThemeBrightness brightness: ThemeBrightness.light, Map<int, Color> primarySwatch, Color accentColor, this.accentColorBrightness: ThemeBrightness.dark, TextTheme text }): this.brightness = brightness, this.primarySwatch = primarySwatch, primaryColorBrightness = primarySwatch == null ? brightness : ThemeBrightness.dark, canvasColor = brightness == ThemeBrightness.dark ? Colors.grey[850] : Colors.grey[50], cardColor = brightness == ThemeBrightness.dark ? Colors.grey[800] : Colors.white, dividerColor = brightness == ThemeBrightness.dark ? const Color(0x1FFFFFFF) : const Color(0x1F000000), // Some users want the pre-multiplied color, others just want the opacity. hintColor = brightness == ThemeBrightness.dark ? const Color(0x42FFFFFF) : const Color(0x4C000000), hintOpacity = brightness == ThemeBrightness.dark ? 0.26 : 0.30, // TODO(eseidel): Where are highlight and selected colors documented? // I flipped highlight/selected to match the News app (which is clearly not quite Material) // Gmail has an interesting behavior of showing selected darker until // you click on a different drawer item when the first one loses its // selected color and becomes lighter, the ink then fills to make the new // click dark to match the previous (resting) selected state. States // revert when you cancel the tap. highlightColor = const Color(0x33999999), selectedColor = const Color(0x66999999), text = brightness == ThemeBrightness.dark ? Typography.white : Typography.black { assert(brightness != null); if (primarySwatch == null) { if (brightness == ThemeBrightness.dark) { _primaryColor = Colors.grey[900]; } else { _primaryColor = Colors.grey[100]; } } else { _primaryColor = primarySwatch[500]; } if (accentColor == null) { _accentColor = primarySwatch == null ? Colors.blue[500] : primarySwatch[500]; } else { _accentColor = accentColor; } } factory ThemeData.light() => new ThemeData(primarySwatch: Colors.blue, brightness: ThemeBrightness.light); factory ThemeData.dark() => new ThemeData(brightness: ThemeBrightness.dark); factory ThemeData.fallback() => new ThemeData.light(); /// The brightness of the overall theme of the application. Used by widgets /// like buttons to determine what color to pick when not using the primary or /// accent color. final ThemeBrightness brightness; final Map<int, Color> primarySwatch; final Color canvasColor; final Color cardColor; final Color dividerColor; final Color hintColor; final Color highlightColor; final Color selectedColor; final double hintOpacity; final TextTheme text; /// The background colour for major parts of the app (toolbars, tab bars, etc) Color get primaryColor => _primaryColor; Color _primaryColor; /// The brightness of the primaryColor. Used to determine the colour of text and /// icons placed on top of the primary color (e.g. toolbar text). final ThemeBrightness primaryColorBrightness; /// A text theme that contrasts with the primary color. TextTheme get primaryTextTheme { if (primaryColorBrightness == ThemeBrightness.dark) return Typography.white; return Typography.black; } IconThemeData get primaryIconTheme { if (primaryColorBrightness == ThemeBrightness.dark) return const IconThemeData(color: IconThemeColor.white); return const IconThemeData(color: IconThemeColor.black); } /// The foreground color for widgets (knobs, text, etc) Color get accentColor => _accentColor; Color _accentColor; /// The brightness of the accentColor. Used to determine the colour of text /// and icons placed on top of the accent color (e.g. the icons on a floating /// action button). final ThemeBrightness accentColorBrightness; bool operator==(Object other) { if (other.runtimeType != runtimeType) return false; ThemeData otherData = other; return (otherData.brightness == brightness) && (otherData.primarySwatch == primarySwatch) && (otherData.canvasColor == canvasColor) && (otherData.cardColor == cardColor) && (otherData.dividerColor == dividerColor) && (otherData.hintColor == hintColor) && (otherData.highlightColor == highlightColor) && (otherData.selectedColor == selectedColor) && (otherData.hintOpacity == hintOpacity) && (otherData.text == text) && (otherData.primaryColorBrightness == primaryColorBrightness) && (otherData.accentColorBrightness == accentColorBrightness); } int get hashCode { int value = 373; value = 37 * value + brightness.hashCode; value = 37 * value + primarySwatch.hashCode; value = 37 * value + canvasColor.hashCode; value = 37 * value + cardColor.hashCode; value = 37 * value + dividerColor.hashCode; value = 37 * value + hintColor.hashCode; value = 37 * value + highlightColor.hashCode; value = 37 * value + selectedColor.hashCode; value = 37 * value + hintOpacity.hashCode; value = 37 * value + text.hashCode; value = 37 * value + primaryColorBrightness.hashCode; value = 37 * value + accentColorBrightness.hashCode; return value; } String toString() => '$primaryColor $brightness etc...'; }