[Gallery] Preserve demo state, simplify demo width calculations on desktop (#287)

* Maintain state on mobile

* Refactor section width code

* Fix state resetting on desktop

* Remove unused import

* Remove unecessary GestureDetectorBehavior
pull/292/head
Pierre-Louis 6 years ago committed by GitHub
parent 4e0b2e7b21
commit 5fe2c22309
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -3,7 +3,6 @@
// found in the LICENSE file. // found in the LICENSE file.
import 'dart:io' show Platform; import 'dart:io' show Platform;
import 'dart:math';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -256,12 +255,14 @@ class _DemoPageState extends State<DemoPage> with TickerProviderStateMixin {
appBar.preferredSize.height; appBar.preferredSize.height;
final maxSectionHeight = isDesktop ? contentHeight : contentHeight - 64; final maxSectionHeight = isDesktop ? contentHeight : contentHeight - 64;
final horizontalPadding = isDesktop ? mediaQuery.size.width * 0.12 : 0.0; final horizontalPadding = isDesktop ? mediaQuery.size.width * 0.12 : 0.0;
final maxSectionWidth = 420.0;
Widget section; Widget section;
switch (_state) { switch (_state) {
case _DemoState.options: case _DemoState.options:
section = _DemoSectionOptions( section = _DemoSectionOptions(
maxHeight: maxSectionHeight, maxHeight: maxSectionHeight,
maxWidth: maxSectionWidth,
configurations: widget.demo.configurations, configurations: widget.demo.configurations,
configIndex: _configIndex, configIndex: _configIndex,
onConfigChanged: (index) { onConfigChanged: (index) {
@ -277,6 +278,7 @@ class _DemoPageState extends State<DemoPage> with TickerProviderStateMixin {
case _DemoState.info: case _DemoState.info:
section = _DemoSectionInfo( section = _DemoSectionInfo(
maxHeight: maxSectionHeight, maxHeight: maxSectionHeight,
maxWidth: maxSectionWidth,
title: _currentConfig.title, title: _currentConfig.title,
description: _currentConfig.description, description: _currentConfig.description,
); );
@ -314,46 +316,15 @@ class _DemoPageState extends State<DemoPage> with TickerProviderStateMixin {
buildRoute: _currentConfig.buildRoute, buildRoute: _currentConfig.buildRoute,
); );
if (isDesktop) { if (isDesktop) {
// If the available width is not very wide, reduce the amount of space final isFullScreen = _state == _DemoState.fullscreen;
// between the demo content and the selected section. final Widget sectionAndDemo = Row(
const reducedMiddleSpaceWidth = 48.0; crossAxisAlignment: CrossAxisAlignment.start,
children: [
// Width of the space between the section and the demo content if (!isFullScreen) Expanded(child: section),
// when the code is NOT displayed. SizedBox(width: !isFullScreen ? 48.0 : 0),
final nonCodePageMiddleSpaceWidth = mediaQuery.size.width > 900 Expanded(child: demoContent),
? horizontalPadding ],
: reducedMiddleSpaceWidth; );
// Width of the space between the section and the demo content
// when the code is displayed.
final codePageMiddleSpaceWidth =
min(reducedMiddleSpaceWidth, nonCodePageMiddleSpaceWidth);
// Width of the space between the section and the demo content
final middleSpaceWidth = _state == _DemoState.code
? codePageMiddleSpaceWidth
: nonCodePageMiddleSpaceWidth;
// Width for demo content.
// It is calculated in this way because the code demands more space.
final demoContentWidth = (mediaQuery.size.width -
horizontalPadding * 2 -
nonCodePageMiddleSpaceWidth) /
2;
final Widget sectionAndDemo = (_state == _DemoState.fullscreen)
? demoContent
: Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(child: section),
SizedBox(width: middleSpaceWidth),
Container(
width: demoContentWidth,
child: demoContent,
),
],
);
body = SafeArea( body = SafeArea(
child: Padding( child: Padding(
@ -371,20 +342,22 @@ class _DemoPageState extends State<DemoPage> with TickerProviderStateMixin {
); );
// Add a tap gesture to collapse the currently opened section. // Add a tap gesture to collapse the currently opened section.
if (_state != _DemoState.normal) { demoContent = Semantics(
demoContent = Semantics( label: MaterialLocalizations.of(context).modalBarrierDismissLabel,
label: MaterialLocalizations.of(context).modalBarrierDismissLabel, child: GestureDetector(
child: GestureDetector( onTap: () {
behavior: HitTestBehavior.opaque, if (_state != _DemoState.normal) {
onTap: () {
setStateAndUpdate(() { setStateAndUpdate(() {
_state = _DemoState.normal; _state = _DemoState.normal;
}); });
}, }
child: ExcludeSemantics(child: demoContent), },
child: Semantics(
excludeSemantics: _state != _DemoState.normal,
child: demoContent,
), ),
); ),
} );
body = SafeArea( body = SafeArea(
bottom: false, bottom: false,
@ -491,12 +464,14 @@ class _DemoSectionOptions extends StatelessWidget {
const _DemoSectionOptions({ const _DemoSectionOptions({
Key key, Key key,
this.maxHeight, this.maxHeight,
this.maxWidth,
this.configurations, this.configurations,
this.configIndex, this.configIndex,
this.onConfigChanged, this.onConfigChanged,
}) : super(key: key); }) : super(key: key);
final double maxHeight; final double maxHeight;
final double maxWidth;
final List<GalleryDemoConfiguration> configurations; final List<GalleryDemoConfiguration> configurations;
final int configIndex; final int configIndex;
final ValueChanged<int> onConfigChanged; final ValueChanged<int> onConfigChanged;
@ -506,49 +481,52 @@ class _DemoSectionOptions extends StatelessWidget {
final textTheme = Theme.of(context).textTheme; final textTheme = Theme.of(context).textTheme;
final colorScheme = Theme.of(context).colorScheme; final colorScheme = Theme.of(context).colorScheme;
return Container( return Align(
constraints: BoxConstraints(maxHeight: maxHeight), alignment: AlignmentDirectional.topStart,
child: Column( child: Container(
crossAxisAlignment: CrossAxisAlignment.start, constraints: BoxConstraints(maxHeight: maxHeight, maxWidth: maxWidth),
mainAxisSize: MainAxisSize.min, child: Column(
children: [ crossAxisAlignment: CrossAxisAlignment.start,
Padding( mainAxisSize: MainAxisSize.min,
padding: const EdgeInsetsDirectional.only( children: [
start: 24, Padding(
top: 12, padding: const EdgeInsetsDirectional.only(
end: 24, start: 24,
), top: 12,
child: Text( end: 24,
GalleryLocalizations.of(context).demoOptionsTooltip, ),
style: textTheme.display1.apply( child: Text(
color: colorScheme.onSurface, GalleryLocalizations.of(context).demoOptionsTooltip,
fontSizeDelta: style: textTheme.display1.apply(
isDisplayDesktop(context) ? desktopDisplay1FontDelta : 0, color: colorScheme.onSurface,
fontSizeDelta:
isDisplayDesktop(context) ? desktopDisplay1FontDelta : 0,
),
), ),
), ),
), Divider(
Divider( thickness: 1,
thickness: 1, height: 16,
height: 16, color: colorScheme.onSurface,
color: colorScheme.onSurface,
),
Flexible(
child: ListView(
shrinkWrap: true,
children: [
for (final configuration in configurations)
_DemoSectionOptionsItem(
title: configuration.title,
isSelected: configuration == configurations[configIndex],
onTap: () {
onConfigChanged(configurations.indexOf(configuration));
},
),
],
), ),
), Flexible(
SizedBox(height: 12), child: ListView(
], shrinkWrap: true,
children: [
for (final configuration in configurations)
_DemoSectionOptionsItem(
title: configuration.title,
isSelected: configuration == configurations[configIndex],
onTap: () {
onConfigChanged(configurations.indexOf(configuration));
},
),
],
),
),
SizedBox(height: 12),
],
),
), ),
); );
} }
@ -594,11 +572,13 @@ class _DemoSectionInfo extends StatelessWidget {
const _DemoSectionInfo({ const _DemoSectionInfo({
Key key, Key key,
this.maxHeight, this.maxHeight,
this.maxWidth,
this.title, this.title,
this.description, this.description,
}) : super(key: key); }) : super(key: key);
final double maxHeight; final double maxHeight;
final double maxWidth;
final String title; final String title;
final String description; final String description;
@ -607,33 +587,36 @@ class _DemoSectionInfo extends StatelessWidget {
final textTheme = Theme.of(context).textTheme; final textTheme = Theme.of(context).textTheme;
final colorScheme = Theme.of(context).colorScheme; final colorScheme = Theme.of(context).colorScheme;
return Container( return Align(
padding: const EdgeInsetsDirectional.only( alignment: AlignmentDirectional.topStart,
start: 24, child: Container(
top: 12, padding: const EdgeInsetsDirectional.only(
end: 24, start: 24,
bottom: 32, top: 12,
), end: 24,
constraints: BoxConstraints(maxHeight: maxHeight), bottom: 32,
child: SingleChildScrollView( ),
child: Column( constraints: BoxConstraints(maxHeight: maxHeight, maxWidth: maxWidth),
crossAxisAlignment: CrossAxisAlignment.start, child: SingleChildScrollView(
mainAxisSize: MainAxisSize.min, child: Column(
children: [ crossAxisAlignment: CrossAxisAlignment.start,
Text( mainAxisSize: MainAxisSize.min,
title, children: [
style: textTheme.display1.apply( Text(
color: colorScheme.onSurface, title,
fontSizeDelta: style: textTheme.display1.apply(
isDisplayDesktop(context) ? desktopDisplay1FontDelta : 0, color: colorScheme.onSurface,
fontSizeDelta:
isDisplayDesktop(context) ? desktopDisplay1FontDelta : 0,
),
), ),
), SizedBox(height: 12),
SizedBox(height: 12), Text(
Text( description,
description, style: textTheme.body1.apply(color: colorScheme.onSurface),
style: textTheme.body1.apply(color: colorScheme.onSurface), ),
), ],
], ),
), ),
), ),
); );

Loading…
Cancel
Save