blob: d3daf7a4af4389a59c1efc2ea901fa76d450aa46 [file] [log] [blame]
// Copyright 2019 The Flutter team. 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/material.dart';
import 'package:scoped_model/scoped_model.dart';
import 'package:gallery/data/gallery_options.dart';
import 'package:gallery/l10n/gallery_localizations.dart';
import 'package:gallery/layout/adaptive.dart';
import 'package:gallery/layout/text_scale.dart';
import 'package:gallery/studies/shrine/colors.dart';
import 'package:gallery/studies/shrine/login.dart';
import 'package:gallery/studies/shrine/model/app_state_model.dart';
import 'package:gallery/studies/shrine/model/product.dart';
import 'package:gallery/studies/shrine/page_status.dart';
import 'package:gallery/studies/shrine/triangle_category_indicator.dart';
double desktopCategoryMenuPageWidth({
BuildContext context,
}) {
return 232 * reducedTextScale(context);
}
class CategoryMenuPage extends StatelessWidget {
const CategoryMenuPage({
Key key,
this.onCategoryTap,
}) : super(key: key);
final VoidCallback onCategoryTap;
Widget _buttonText(String caption, TextStyle style) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 16),
child: Text(
caption,
style: style,
textAlign: TextAlign.center,
),
);
}
Widget _divider({BuildContext context}) {
return Container(
width: 56 * GalleryOptions.of(context).textScaleFactor(context),
height: 1,
color: Color(0xFF8F716D),
);
}
Widget _buildCategory(Category category, BuildContext context) {
final bool isDesktop = isDisplayDesktop(context);
final String categoryString = category.name(context);
final TextStyle selectedCategoryTextStyle = Theme.of(context)
.textTheme
.body2
.copyWith(fontSize: isDesktop ? 17 : 19);
final TextStyle unselectedCategoryTextStyle = selectedCategoryTextStyle
.copyWith(color: shrineBrown900.withOpacity(0.6));
final double indicatorHeight = (isDesktop ? 28 : 30) *
GalleryOptions.of(context).textScaleFactor(context);
final double indicatorWidth = indicatorHeight * 34 / 28;
return ScopedModelDescendant<AppStateModel>(
builder: (context, child, model) => Semantics(
selected: model.selectedCategory == category,
button: true,
child: GestureDetector(
onTap: () {
model.setCategory(category);
if (onCategoryTap != null) {
onCategoryTap();
}
},
child: model.selectedCategory == category
? CustomPaint(
painter: TriangleCategoryIndicator(
indicatorWidth,
indicatorHeight,
),
child: _buttonText(categoryString, selectedCategoryTextStyle),
)
: _buttonText(categoryString, unselectedCategoryTextStyle),
),
),
);
}
@override
Widget build(BuildContext context) {
final bool isDesktop = isDisplayDesktop(context);
final TextStyle logoutTextStyle =
Theme.of(context).textTheme.body2.copyWith(
fontSize: isDesktop ? 17 : 19,
color: shrineBrown900.withOpacity(0.6),
);
if (isDesktop) {
return AnimatedBuilder(
animation: PageStatus.of(context).cartController,
builder: (context, child) => ExcludeSemantics(
excluding: !menuPageIsVisible(context),
child: Material(
child: Container(
color: shrinePink100,
width: desktopCategoryMenuPageWidth(context: context),
child: Column(
children: [
const SizedBox(height: 64),
Image.asset(
'packages/shrine_images/diamond.png',
excludeFromSemantics: true,
),
const SizedBox(height: 16),
Semantics(
container: true,
child: Text(
'SHRINE',
style: Theme.of(context).textTheme.headline,
),
),
const Spacer(),
for (final category in categories)
_buildCategory(category, context),
_divider(context: context),
Semantics(
button: true,
child: GestureDetector(
onTap: () {
Navigator.push<void>(
context,
MaterialPageRoute<void>(
builder: (context) => LoginPage(),
),
);
},
child: _buttonText(
GalleryLocalizations.of(context)
.shrineLogoutButtonCaption,
logoutTextStyle,
),
),
),
const Spacer(),
IconButton(
icon: const Icon(Icons.search),
tooltip:
GalleryLocalizations.of(context).shrineTooltipSearch,
onPressed: () {},
),
const SizedBox(height: 72),
],
),
),
),
),
);
} else {
return AnimatedBuilder(
animation: PageStatus.of(context).cartController,
builder: (context, child) => AnimatedBuilder(
animation: PageStatus.of(context).menuController,
builder: (context, child) => ExcludeSemantics(
excluding: !menuPageIsVisible(context),
child: Center(
child: Container(
padding: const EdgeInsets.only(top: 40),
color: shrinePink100,
child: ListView(
children: [
for (final category in categories)
_buildCategory(category, context),
Center(
child: _divider(context: context),
),
Semantics(
button: true,
child: GestureDetector(
onTap: () {
if (onCategoryTap != null) {
onCategoryTap();
}
Navigator.push<void>(
context,
MaterialPageRoute<void>(
builder: (context) => LoginPage()),
);
},
child: _buttonText(
GalleryLocalizations.of(context)
.shrineLogoutButtonCaption,
logoutTextStyle,
),
),
),
],
),
),
),
),
),
);
}
}
}