|
|
|
|
|
|
using Unity.UIWidgets.ui; |
|
|
|
using Unity.UIWidgets.widgets; |
|
|
|
using UnityEngine; |
|
|
|
using AsyncCallback = Unity.UIWidgets.foundation.AsyncCallback; |
|
|
|
using Color = Unity.UIWidgets.ui.Color; |
|
|
|
using TextStyle = Unity.UIWidgets.painting.TextStyle; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public override Size preferredSize { get; } |
|
|
|
|
|
|
|
public bool? _getEffectiveCenterTitle(ThemeData themeData) { |
|
|
|
public bool? _getEffectiveCenterTitle(ThemeData theme) { |
|
|
|
switch (themeData.platform) { |
|
|
|
D.assert(theme.platform != null); |
|
|
|
|
|
|
|
switch (theme.platform) { |
|
|
|
case RuntimePlatform.Android: |
|
|
|
case RuntimePlatform.LinuxEditor: |
|
|
|
case RuntimePlatform.LinuxPlayer: |
|
|
|
case RuntimePlatform.WindowsEditor: |
|
|
|
case RuntimePlatform.WindowsPlayer: |
|
|
|
return false; |
|
|
|
case RuntimePlatform.OSXEditor: |
|
|
|
case RuntimePlatform.OSXPlayer: |
|
|
|
return actions == null || actions.Count < 2; |
|
|
|
default: |
|
|
|
return false; |
|
|
|
|
|
|
|
|
|
|
public override Widget build(BuildContext context) { |
|
|
|
D.assert(material_.debugCheckHasMaterialLocalizations(context)); |
|
|
|
ThemeData themeData = Theme.of(context); |
|
|
|
ThemeData theme = Theme.of(context); |
|
|
|
AppBarTheme appBarTheme = AppBarTheme.of(context); |
|
|
|
ScaffoldState scaffold = Scaffold.of(context, nullOk: true); |
|
|
|
ModalRoute parentRoute = ModalRoute.of(context); |
|
|
|
|
|
|
bool useCloseButton = parentRoute is PageRoute && ((PageRoute) parentRoute).fullscreenDialog; |
|
|
|
|
|
|
|
IconThemeData overallIconTheme = widget.iconTheme |
|
|
|
?? appBarTheme.iconTheme |
|
|
|
?? themeData.primaryIconTheme; |
|
|
|
?? appBarTheme.iconTheme |
|
|
|
?? theme.primaryIconTheme; |
|
|
|
TextStyle centerStyle = widget.textTheme?.title |
|
|
|
?? appBarTheme.textTheme?.title |
|
|
|
?? themeData.primaryTextTheme.title; |
|
|
|
TextStyle sideStyle = widget.textTheme?.body1 |
|
|
|
?? appBarTheme.textTheme?.body1 |
|
|
|
?? themeData.primaryTextTheme.body1; |
|
|
|
TextStyle centerStyle = widget.textTheme?.headline6 |
|
|
|
?? appBarTheme.textTheme?.headline6 |
|
|
|
?? theme.primaryTextTheme.headline6; |
|
|
|
TextStyle sideStyle = widget.textTheme?.bodyText2 |
|
|
|
?? appBarTheme.textTheme?.bodyText2 |
|
|
|
?? theme.primaryTextTheme.bodyText2; |
|
|
|
|
|
|
|
if (widget.toolbarOpacity != 1.0f) { |
|
|
|
float opacity = |
|
|
|
|
|
|
|
|
|
|
Widget title = widget.title; |
|
|
|
if (title != null) { |
|
|
|
bool namesRoute; |
|
|
|
|
|
|
|
switch (theme.platform) { |
|
|
|
case RuntimePlatform.Android: |
|
|
|
case RuntimePlatform.LinuxEditor: |
|
|
|
case RuntimePlatform.LinuxPlayer: |
|
|
|
case RuntimePlatform.WindowsEditor: |
|
|
|
case RuntimePlatform.WindowsPlayer: |
|
|
|
namesRoute = true; |
|
|
|
break; |
|
|
|
case RuntimePlatform.IPhonePlayer: |
|
|
|
case RuntimePlatform.OSXEditor: |
|
|
|
case RuntimePlatform.OSXPlayer: |
|
|
|
break; |
|
|
|
default: |
|
|
|
break; |
|
|
|
} |
|
|
|
|
|
|
|
title = new _AppBarTitleBox(child: title); |
|
|
|
|
|
|
|
child: title); |
|
|
|
child: title |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
Widget actions = null; |
|
|
|
|
|
|
leading: leading, |
|
|
|
middle: title, |
|
|
|
trailing: actions, |
|
|
|
centerMiddle: widget._getEffectiveCenterTitle(themeData).Value, |
|
|
|
centerMiddle: widget._getEffectiveCenterTitle(theme).Value, |
|
|
|
middleSpacing: widget.titleSpacing); |
|
|
|
|
|
|
|
Widget appBar = new ClipRect( |
|
|
|
|
|
|
|
|
|
|
if (widget.primary) { |
|
|
|
appBar = new SafeArea( |
|
|
|
bottom: false, |
|
|
|
top: true, |
|
|
|
child: appBar); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
Brightness brightness = widget.brightness |
|
|
|
?? appBarTheme.brightness |
|
|
|
?? themeData.primaryColorBrightness; |
|
|
|
?? theme.primaryColorBrightness; |
|
|
|
SystemUiOverlayStyle overlayStyle = brightness == Brightness.dark |
|
|
|
? SystemUiOverlayStyle.light |
|
|
|
: SystemUiOverlayStyle.dark; |
|
|
|
|
|
|
child: new Material( |
|
|
|
color: widget.backgroundColor |
|
|
|
?? appBarTheme.color |
|
|
|
?? themeData.primaryColor, |
|
|
|
?? theme.primaryColor, |
|
|
|
elevation: widget.elevation |
|
|
|
?? appBarTheme.elevation |
|
|
|
?? _defaultElevation, |
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
RenderSliverFloatingPersistentHeader _headerRenderer() { |
|
|
|
return (RenderSliverFloatingPersistentHeader) context.ancestorRenderObjectOfType( |
|
|
|
new TypeMatcher<RenderSliverFloatingPersistentHeader>()); |
|
|
|
return context.findAncestorRenderObjectOfType<RenderSliverFloatingPersistentHeader>(); |
|
|
|
} |
|
|
|
|
|
|
|
void _isScrollingListener() { |
|
|
|
|
|
|
float? topPadding, |
|
|
|
bool floating, |
|
|
|
bool pinned, |
|
|
|
FloatingHeaderSnapConfiguration snapConfiguration |
|
|
|
FloatingHeaderSnapConfiguration snapConfiguration, |
|
|
|
OverScrollHeaderStretchConfiguration stretchConfiguration, |
|
|
|
ShapeBorder shape |
|
|
|
) { |
|
|
|
D.assert(primary || topPadding == 0.0); |
|
|
|
this.leading = leading; |
|
|
|
|
|
|
this.topPadding = topPadding; |
|
|
|
this.floating = floating; |
|
|
|
this.pinned = pinned; |
|
|
|
_snapConfiguration = snapConfiguration; |
|
|
|
this.snapConfiguration = snapConfiguration; |
|
|
|
this.snapConfiguration = snapConfiguration; |
|
|
|
this.stretchConfiguration = stretchConfiguration; |
|
|
|
} |
|
|
|
|
|
|
|
public readonly Widget leading; |
|
|
|
|
|
|
public readonly float? topPadding; |
|
|
|
public readonly bool floating; |
|
|
|
public readonly bool pinned; |
|
|
|
public readonly ShapeBorder shape; |
|
|
|
|
|
|
|
readonly float _bottomHeight; |
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public override FloatingHeaderSnapConfiguration snapConfiguration { |
|
|
|
get { return _snapConfiguration; } |
|
|
|
} |
|
|
|
public override FloatingHeaderSnapConfiguration snapConfiguration { get; } |
|
|
|
FloatingHeaderSnapConfiguration _snapConfiguration; |
|
|
|
public override OverScrollHeaderStretchConfiguration stretchConfiguration { get; } |
|
|
|
|
|
|
|
public override Widget build(BuildContext context, float shrinkOffset, bool overlapsContent) { |
|
|
|
float? visibleMainHeight = maxExtent - shrinkOffset - topPadding; |
|
|
|
|
|
|
primary: primary, |
|
|
|
centerTitle: centerTitle, |
|
|
|
titleSpacing: titleSpacing, |
|
|
|
shape: shape, |
|
|
|
toolbarOpacity: toolbarOpacity, |
|
|
|
bottomOpacity: pinned |
|
|
|
? 1.0f |
|
|
|
|
|
|
|| topPadding != oldDelegate.topPadding |
|
|
|
|| pinned != oldDelegate.pinned |
|
|
|
|| floating != oldDelegate.floating |
|
|
|
|| snapConfiguration != oldDelegate.snapConfiguration; |
|
|
|
|| snapConfiguration != oldDelegate.snapConfiguration |
|
|
|
|| stretchConfiguration != oldDelegate.stretchConfiguration; |
|
|
|
} |
|
|
|
|
|
|
|
public override string ToString() { |
|
|
|
|
|
|
float? expandedHeight = null, |
|
|
|
bool floating = false, |
|
|
|
bool pinned = false, |
|
|
|
bool snap = false |
|
|
|
bool snap = false, |
|
|
|
bool stretch = false, |
|
|
|
float stretchTriggerOffset = 100.0f, |
|
|
|
AsyncCallback onStretchTrigger = null, |
|
|
|
ShapeBorder shape = null |
|
|
|
D.assert(stretchTriggerOffset > 0.0); |
|
|
|
|
|
|
|
this.leading = leading; |
|
|
|
this.automaticallyImplyLeading = true; |
|
|
|
this.title = title; |
|
|
|
|
|
|
this.floating = floating; |
|
|
|
this.pinned = pinned; |
|
|
|
this.snap = snap; |
|
|
|
this.stretch = stretch; |
|
|
|
this.stretchTriggerOffset = stretchTriggerOffset; |
|
|
|
this.onStretchTrigger = onStretchTrigger; |
|
|
|
this.shape = shape; |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public readonly Brightness? brightness; |
|
|
|
|
|
|
|
public readonly IconThemeData iconTheme; |
|
|
|
|
|
|
|
|
|
|
|
public readonly IconThemeData actionsIconTheme; |
|
|
|
|
|
|
|
public readonly TextTheme textTheme; |
|
|
|
|
|
|
public readonly bool? centerTitle; |
|
|
|
|
|
|
|
public readonly bool? excludeHeaderSemantics; |
|
|
|
|
|
|
|
public readonly float titleSpacing; |
|
|
|
|
|
|
|
public readonly float? expandedHeight; |
|
|
|
|
|
|
public readonly bool pinned; |
|
|
|
|
|
|
|
public readonly ShapeBorder shape; |
|
|
|
|
|
|
|
public readonly bool stretch; |
|
|
|
|
|
|
|
public readonly float stretchTriggerOffset; |
|
|
|
|
|
|
|
public readonly AsyncCallback onStretchTrigger; |
|
|
|
|
|
|
|
public override State createState() { |
|
|
|
return new _SliverAppBarState(); |
|
|
|
|
|
|
class _SliverAppBarState : TickerProviderStateMixin<SliverAppBar> { |
|
|
|
FloatingHeaderSnapConfiguration _snapConfiguration; |
|
|
|
OverScrollHeaderStretchConfiguration _stretchConfiguration; |
|
|
|
|
|
|
|
void _updateSnapConfiguration() { |
|
|
|
if (widget.snap && widget.floating) { |
|
|
|
|
|
|
_snapConfiguration = null; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void _updateStretchConfiguration() { |
|
|
|
if (widget.stretch) { |
|
|
|
_stretchConfiguration = new OverScrollHeaderStretchConfiguration( |
|
|
|
stretchTriggerOffset: widget.stretchTriggerOffset, |
|
|
|
onStretchTrigger: widget.onStretchTrigger |
|
|
|
); |
|
|
|
} else { |
|
|
|
_stretchConfiguration = null; |
|
|
|
} |
|
|
|
} |
|
|
|
_updateStretchConfiguration(); |
|
|
|
} |
|
|
|
|
|
|
|
public override void didUpdateWidget(StatefulWidget _oldWidget) { |
|
|
|
|
|
|
_updateSnapConfiguration(); |
|
|
|
} |
|
|
|
|
|
|
|
if (widget.stretch != oldWidget.stretch) { |
|
|
|
_updateStretchConfiguration(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
public override Widget build(BuildContext context) { |
|
|
|
|
|
|
topPadding: topPadding, |
|
|
|
floating: widget.floating, |
|
|
|
pinned: widget.pinned, |
|
|
|
snapConfiguration: _snapConfiguration |
|
|
|
shape: widget.shape, |
|
|
|
snapConfiguration: _snapConfiguration, |
|
|
|
stretchConfiguration: _stretchConfiguration |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
internal class _AppBarTitleBox : SingleChildRenderObjectWidget { |
|
|
|
internal _AppBarTitleBox(Key key = null, Widget child = null) : base(key: key, child: child) { |
|
|
|
D.assert(child != null); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
public override RenderObject createRenderObject(BuildContext context) { |
|
|
|
return new _RenderAppBarTitleBox( |
|
|
|
textDirection: Directionality.of(context) |
|
|
|
); |
|
|
|
} |
|
|
|
|
|
|
|
public override void updateRenderObject(BuildContext context, RenderObject renderObject) { |
|
|
|
if (renderObject is _RenderAppBarTitleBox renderAppBarTitleBox) { |
|
|
|
renderAppBarTitleBox.textDirection = Directionality.of(context); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
class _RenderAppBarTitleBox : RenderAligningShiftedBox { |
|
|
|
internal _RenderAppBarTitleBox( |
|
|
|
RenderBox child = null, |
|
|
|
TextDirection textDirection = TextDirection.ltr |
|
|
|
) : base(child: child, alignment: Alignment.center, textDirection: textDirection) { |
|
|
|
} |
|
|
|
|
|
|
|
protected override void performLayout() { |
|
|
|
BoxConstraints constraints = this.constraints; |
|
|
|
BoxConstraints innerConstraints = constraints.copyWith(maxHeight: float.PositiveInfinity); |
|
|
|
child.layout(innerConstraints, parentUsesSize: true); |
|
|
|
size = constraints.constrain(child.size); |
|
|
|
alignChild(); |
|
|
|
} |
|
|
|
} |
|
|
|
} |