// Copyright 2018 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 'package:flutter_web/material.dart'; import 'sections.dart'; const double kSectionIndicatorWidth = 32.0; // The card for a single section. Displays the section's gradient and background image. class SectionCard extends StatelessWidget { const SectionCard({Key key, @required this.section}) : assert(section != null), super(key: key); final Section section; @override Widget build(BuildContext context) { return Semantics( label: section.title, button: true, child: DecoratedBox( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.centerLeft, end: Alignment.centerRight, colors: [ section.leftColor, section.rightColor, ], ), ), // TODO(b:119312219): Remove Opacity layer when Image Color Filter // is implemented in paintImage. child: Opacity( opacity: 0.075, child: Image.asset( section.backgroundAsset, package: section.backgroundAssetPackage, color: const Color.fromRGBO(255, 255, 255, 0.075), colorBlendMode: BlendMode.modulate, fit: BoxFit.cover, ), ), ), ); } } // The title is rendered with two overlapping text widgets that are vertically // offset a little. It's supposed to look sort-of 3D. class SectionTitle extends StatelessWidget { const SectionTitle({ Key key, @required this.section, @required this.scale, @required this.opacity, }) : assert(section != null), assert(scale != null), assert(opacity != null && opacity >= 0.0 && opacity <= 1.0), super(key: key); final Section section; final double scale; final double opacity; static const TextStyle sectionTitleStyle = TextStyle( fontFamily: 'Raleway', inherit: false, fontSize: 24.0, fontWeight: FontWeight.w500, color: Colors.white, textBaseline: TextBaseline.alphabetic, ); static final TextStyle sectionTitleShadowStyle = sectionTitleStyle.copyWith( color: const Color(0x19000000), ); @override Widget build(BuildContext context) { return IgnorePointer( child: Opacity( opacity: opacity, child: Transform( transform: Matrix4.identity()..scale(scale), alignment: Alignment.center, child: Stack( children: [ Positioned( top: 4.0, child: Text(section.title, style: sectionTitleShadowStyle), ), Text(section.title, style: sectionTitleStyle), ], ), ), ), ); } } // Small horizontal bar that indicates the selected section. class SectionIndicator extends StatelessWidget { const SectionIndicator({Key key, this.opacity = 1.0}) : super(key: key); final double opacity; @override Widget build(BuildContext context) { return IgnorePointer( child: Container( width: kSectionIndicatorWidth, height: 3.0, color: Colors.white.withOpacity(opacity), ), ); } } // Display a single SectionDetail. class SectionDetailView extends StatelessWidget { SectionDetailView({Key key, @required this.detail}) : assert(detail != null && detail.imageAsset != null), assert((detail.imageAsset ?? detail.title) != null), super(key: key); final SectionDetail detail; @override Widget build(BuildContext context) { final Widget image = DecoratedBox( decoration: BoxDecoration( borderRadius: BorderRadius.circular(6.0), image: DecorationImage( image: AssetImage( detail.imageAsset, package: detail.imageAssetPackage, ), fit: BoxFit.cover, alignment: Alignment.center, ), ), ); Widget item; if (detail.title == null && detail.subtitle == null) { item = Container( height: 240.0, padding: const EdgeInsets.all(16.0), child: SafeArea( top: false, bottom: false, child: image, ), ); } else { item = ListTile( title: Text(detail.title), subtitle: Text(detail.subtitle), leading: SizedBox(width: 32.0, height: 32.0, child: image), ); } return DecoratedBox( decoration: BoxDecoration(color: Colors.grey.shade200), child: item, ); } }