in lib/pages/demo.dart [241:543]
Widget build(BuildContext context) {
final isDesktop = isDisplayDesktop(context);
_resolveState(context);
final colorScheme = Theme.of(context).colorScheme;
final iconColor = colorScheme.onSurface;
final selectedIconColor = colorScheme.primary;
final appBarPadding = isDesktop ? 20.0 : 0.0;
final currentDemoState = _DemoState.values[_demoStateIndex.value];
final appBar = AppBar(
backgroundColor: Colors.transparent,
leading: Padding(
padding: EdgeInsetsDirectional.only(start: appBarPadding),
child: IconButton(
key: const ValueKey('Back'),
icon: const BackButtonIcon(),
tooltip: MaterialLocalizations.of(context).backButtonTooltip,
onPressed: () {
Navigator.maybePop(context);
},
),
),
actions: [
if (_hasOptions)
IconButton(
icon: FeatureDiscovery(
title: GalleryLocalizations.of(context).demoOptionsFeatureTitle,
description: GalleryLocalizations.of(context)
.demoOptionsFeatureDescription,
showOverlay: _showFeatureHighlightForPlatform(context),
color: colorScheme.primary,
onDismiss: () {
setState(() {
_showFeatureHighlight = false;
});
},
onTap: () {
setState(() {
_showFeatureHighlight = false;
});
},
child: Icon(
Icons.tune,
color: currentDemoState == _DemoState.options ||
_showFeatureHighlightForPlatform(context)
? selectedIconColor
: iconColor,
),
),
tooltip: GalleryLocalizations.of(context).demoOptionsTooltip,
onPressed: () => _handleTap(_DemoState.options),
),
IconButton(
icon: const Icon(Icons.info),
tooltip: GalleryLocalizations.of(context).demoInfoTooltip,
color: currentDemoState == _DemoState.info
? selectedIconColor
: iconColor,
onPressed: () => _handleTap(_DemoState.info),
),
IconButton(
icon: const Icon(Icons.code),
tooltip: GalleryLocalizations.of(context).demoCodeTooltip,
color: currentDemoState == _DemoState.code
? selectedIconColor
: iconColor,
onPressed: () => _handleTap(_DemoState.code),
),
IconButton(
icon: const Icon(Icons.library_books),
tooltip: GalleryLocalizations.of(context).demoDocumentationTooltip,
color: iconColor,
onPressed: () => _showDocumentation(context),
),
if (isDesktop)
IconButton(
icon: const Icon(Icons.fullscreen),
tooltip: GalleryLocalizations.of(context).demoFullscreenTooltip,
color: currentDemoState == _DemoState.fullscreen
? selectedIconColor
: iconColor,
onPressed: () => _handleTap(_DemoState.fullscreen),
),
SizedBox(width: appBarPadding),
],
);
final mediaQuery = MediaQuery.of(context);
final bottomSafeArea = mediaQuery.padding.bottom;
final contentHeight = mediaQuery.size.height -
mediaQuery.padding.top -
mediaQuery.padding.bottom -
appBar.preferredSize.height;
final maxSectionHeight = isDesktop ? contentHeight : contentHeight - 64;
final horizontalPadding = isDesktop ? mediaQuery.size.width * 0.12 : 0.0;
const maxSectionWidth = 420.0;
Widget section;
switch (currentDemoState) {
case _DemoState.options:
section = _DemoSectionOptions(
maxHeight: maxSectionHeight,
maxWidth: maxSectionWidth,
configurations: widget.demo.configurations,
configIndex: _configIndex.value,
onConfigChanged: (index) {
setStateAndUpdate(() {
_configIndex.value = index;
if (!isDesktop) {
_demoStateIndex.value = _DemoState.normal.index;
}
});
},
);
break;
case _DemoState.info:
section = _DemoSectionInfo(
maxHeight: maxSectionHeight,
maxWidth: maxSectionWidth,
title: _currentConfig.title,
description: _currentConfig.description,
);
break;
case _DemoState.code:
final codeTheme = GoogleFonts.robotoMono(
fontSize: 12 * GalleryOptions.of(context).textScaleFactor(context),
);
section = CodeStyle(
baseStyle: codeTheme.copyWith(color: const Color(0xFFFAFBFB)),
numberStyle: codeTheme.copyWith(color: const Color(0xFFBD93F9)),
commentStyle: codeTheme.copyWith(color: const Color(0xFF808080)),
keywordStyle: codeTheme.copyWith(color: const Color(0xFF1CDEC9)),
stringStyle: codeTheme.copyWith(color: const Color(0xFFFFA65C)),
punctuationStyle: codeTheme.copyWith(color: const Color(0xFF8BE9FD)),
classStyle: codeTheme.copyWith(color: const Color(0xFFD65BAD)),
constantStyle: codeTheme.copyWith(color: const Color(0xFFFF8383)),
child: _DemoSectionCode(
maxHeight: maxSectionHeight,
codeWidget: CodeDisplayPage(
_currentConfig.code,
),
),
);
break;
default:
section = Container();
break;
}
Widget body;
Widget demoContent = ScaffoldMessenger(
child: DemoWrapper(
height: contentHeight,
buildRoute: _currentConfig.buildRoute,
),
);
if (isDesktop) {
final isFullScreen = currentDemoState == _DemoState.fullscreen;
final Widget sectionAndDemo = Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (!isFullScreen) Expanded(child: section),
SizedBox(width: !isFullScreen ? 48.0 : 0),
Expanded(child: demoContent),
],
);
body = SafeArea(
child: Padding(
padding: const EdgeInsets.only(top: 56),
child: sectionAndDemo,
),
);
} else {
section = AnimatedSize(
duration: const Duration(milliseconds: 200),
alignment: Alignment.topCenter,
curve: Curves.easeIn,
child: section,
);
final isDemoNormal = currentDemoState == _DemoState.normal;
// Add a tap gesture to collapse the currently opened section.
demoContent = Semantics(
label: MaterialLocalizations.of(context).modalBarrierDismissLabel,
child: MouseRegion(
cursor: isDemoNormal ? MouseCursor.defer : SystemMouseCursors.click,
child: GestureDetector(
onTap: () {
if (!isDemoNormal) {
setStateAndUpdate(() {
_demoStateIndex.value = _DemoState.normal.index;
});
}
},
child: Semantics(
excludeSemantics: !isDemoNormal,
child: demoContent,
),
),
),
);
body = SafeArea(
bottom: false,
child: ListView(
// Use a non-scrollable ListView to enable animation of shifting the
// demo offscreen.
physics: const NeverScrollableScrollPhysics(),
children: [
section,
demoContent,
// Fake the safe area to ensure the animation looks correct.
SizedBox(height: bottomSafeArea),
],
),
);
}
Widget page;
if (isDesktop) {
page = AnimatedBuilder(
animation: _codeBackgroundColorController,
builder: (context, child) {
Brightness themeBrightness;
switch (GalleryOptions.of(context).themeMode) {
case ThemeMode.system:
themeBrightness = MediaQuery.of(context).platformBrightness;
break;
case ThemeMode.light:
themeBrightness = Brightness.light;
break;
case ThemeMode.dark:
themeBrightness = Brightness.dark;
break;
}
Widget contents = Container(
padding: EdgeInsets.symmetric(horizontal: horizontalPadding),
child: ApplyTextOptions(
child: Scaffold(
appBar: appBar,
body: body,
backgroundColor: Colors.transparent,
),
),
);
if (themeBrightness == Brightness.light) {
// If it is currently in light mode, add a
// dark background for code.
Widget codeBackground = Container(
padding: const EdgeInsets.only(top: 56),
child: Container(
color: ColorTween(
begin: Colors.transparent,
end: GalleryThemeData.darkThemeData.canvasColor,
).animate(_codeBackgroundColorController).value,
),
);
contents = Stack(
children: [
codeBackground,
contents,
],
);
}
return Container(
color: colorScheme.background,
child: contents,
);
});
} else {
page = Container(
color: colorScheme.background,
child: ApplyTextOptions(
child: Scaffold(
appBar: appBar,
body: body,
resizeToAvoidBottomInset: false,
),
),
);
}
// Add the splash page functionality for desktop.
if (isDesktop) {
page = MediaQuery.removePadding(
removeTop: true,
context: context,
child: SplashPage(
child: page,
),
);
}
return FeatureDiscoveryController(page);
}