浏览代码

fix s-t

/siyaoH-1.17-PlatformMessage
Shiyun Wen 4 年前
当前提交
6939005b
共有 8 个文件被更改,包括 580 次插入828 次删除
  1. 134
      com.unity.uiwidgets/Runtime/cupertino/slider.cs
  2. 453
      com.unity.uiwidgets/Runtime/cupertino/switch.cs
  3. 63
      com.unity.uiwidgets/Runtime/cupertino/tab_scaffold.cs
  4. 2
      com.unity.uiwidgets/Runtime/cupertino/tab_view.cs
  5. 682
      com.unity.uiwidgets/Runtime/cupertino/text_selection.cs
  6. 71
      com.unity.uiwidgets/Runtime/cupertino/thumb_painter.cs
  7. 2
      com.unity.uiwidgets/Runtime/painting/alignment.cs
  8. 1
      com.unity.uiwidgets/Runtime/rendering/custom_paint.cs

134
com.unity.uiwidgets/Runtime/cupertino/slider.cs


public static readonly Color _kTrackColor = new Color(0xFFB5B5B5);
public const float _kSliderHeight = 2.0f * (CupertinoThumbPainter.radius + _kPadding);
public const float _kSliderWidth = 176.0f; // Matches Material Design slider.
public static readonly TimeSpan _kDiscreteTransitionDuration = new TimeSpan(0, 0, 0, 0, 500);
public static readonly TimeSpan _kDiscreteTransitionDuration = TimeSpan.FromMilliseconds(500);
public const float _kAdjustmentUnit = 0.1f; // Matches iOS implementation of material slider.
}

float min = 0.0f,
float max = 1.0f,
int? divisions = null,
Color activeColor = null
Color activeColor = null,
Color thumbColor = null
D.assert(thumbColor != null);
this.value = value.Value;
this.onChanged = onChanged;
this.onChangeStart = onChangeStart;

this.divisions = divisions;
this.activeColor = activeColor;
this.thumbColor = thumbColor ?? CupertinoColors.white;
}
public readonly float value;

public readonly int? divisions;
public readonly Color activeColor;
public readonly Color thumbColor;
public override State createState() {
return new _CupertinoSliderState();

return new _CupertinoSliderRenderObjectWidget(
value: (widget.value - widget.min) / (widget.max - widget.min),
divisions: widget.divisions,
activeColor: widget.activeColor ?? CupertinoTheme.of(context).primaryColor,
activeColor: CupertinoDynamicColor.resolve(
widget.activeColor ?? CupertinoTheme.of(context).primaryColor,
context
),
thumbColor: widget.thumbColor,
onChanged: widget.onChanged != null ? (ValueChanged<float>) _handleChanged : null,
onChangeStart: widget.onChangeStart != null ? (ValueChanged<float>) _handleDragStart : null,
onChangeEnd: widget.onChangeEnd != null ? (ValueChanged<float>) _handleDragEnd : null,

float? value = null,
int? divisions = null,
Color activeColor = null,
Color thumbColor = null,
ValueChanged<float> onChanged = null,
ValueChanged<float> onChangeStart = null,
ValueChanged<float> onChangeEnd = null,

this.onChangeStart = onChangeStart;
this.onChangeEnd = onChangeEnd;
this.vsync = vsync;
this.thumbColor = thumbColor;
public readonly Color thumbColor;
public readonly ValueChanged<float> onChanged;
public readonly ValueChanged<float> onChangeStart;
public readonly ValueChanged<float> onChangeEnd;

value: value ?? 0.0f,
divisions: divisions,
activeColor: activeColor,
thumbColor: CupertinoDynamicColor.resolve(thumbColor, context),
trackColor: CupertinoDynamicColor.resolve(CupertinoColors.systemFill, context),
vsync: vsync
vsync: vsync,
textDirection: Directionality.of(context)
);
}

renderObject.divisions = divisions;
renderObject.activeColor = activeColor;
renderObject.thumbColor = CupertinoDynamicColor.resolve(thumbColor, context);
renderObject.trackColor = CupertinoDynamicColor.resolve(CupertinoColors.systemFill, context);
renderObject.textDirection = Directionality.of(context);
}
}

int? divisions = null,
Color activeColor = null,
Color thumbColor = null,
Color trackColor = null,
TickerProvider vsync = null
TickerProvider vsync = null,
TextDirection? textDirection = null
D.assert(value >= 0.0f && value <= 1.0f);
D.assert(value >= 0.0f && value <= 1.0f && value != null) ;
_thumbColor = thumbColor;
_trackColor = trackColor;
_textDirection = textDirection;
_drag = new HorizontalDragGestureRecognizer();
_drag.onStart = _handleDragStart;
_drag.onUpdate = _handleDragUpdate;

Color _activeColor;
public Color thumbColor {
get {
return _thumbColor;
}
set {
if (value == _thumbColor)
return;
_thumbColor = value;
markNeedsPaint();
}
}
Color _thumbColor;
public Color trackColor {
get {
return _trackColor;
}
set {
if (value == _trackColor)
return;
_trackColor = value;
markNeedsPaint();
}
}
Color _trackColor;
public ValueChanged<float> onChanged {
get { return _onChanged; }
set {

public ValueChanged<float> onChangeStart;
public ValueChanged<float> onChangeEnd;
public TextDirection? textDirection {
get {
return _textDirection;
}
set {
D.assert(value != null);
if (_textDirection == value)
return;
_textDirection = value;
markNeedsPaint();
}
}
TextDirection? _textDirection;
AnimationController _position;

float _thumbCenter {
get {
float visualPosition = _value;
return MathUtils.lerpFloat(_trackLeft + CupertinoThumbPainter.radius,
_trackRight - CupertinoThumbPainter.radius,
visualPosition);
float visualPosition = 0.0f;
switch (textDirection) {
case TextDirection.rtl:
visualPosition = 1.0f - _value;
break;
case TextDirection.ltr:
visualPosition = _value;
break;
}
return MathUtils.lerpFloat(_trackLeft + CupertinoThumbPainter.radius, _trackRight - CupertinoThumbPainter.radius, visualPosition);
}
}

float extent = Mathf.Max(SliderUtils._kPadding,
size.width - 2.0f * (SliderUtils._kPadding + CupertinoThumbPainter.radius));
float? valueDelta = details.primaryDelta / extent;
_currentDragValue += valueDelta ?? 0.0f;
switch (textDirection) {
case TextDirection.rtl:
_currentDragValue -= valueDelta ?? 0.0f;
break;
case TextDirection.ltr:
_currentDragValue += valueDelta ?? 0.0f;
break;
}
}
}

CupertinoThumbPainter _thumbPainter = new CupertinoThumbPainter();
public override
void paint(PaintingContext context, Offset offset) {
float visualPosition;
Color leftColor;
Color rightColor;
visualPosition = _position.value;
leftColor = SliderUtils._kTrackColor;
rightColor = _activeColor;
public override void paint(PaintingContext context, Offset offset) {
float visualPosition = 0.0f;
Color leftColor = null ;
Color rightColor = null;
switch (textDirection) {
case TextDirection.rtl:
visualPosition = 1.0f - _position.value;
leftColor = _activeColor;
rightColor = trackColor;
break;
case TextDirection.ltr:
visualPosition = _position.value;
leftColor = trackColor;
rightColor = _activeColor;
break;
}
float trackCenter = offset.dy + size.height / 2.0f;
float trackLeft = offset.dx + _trackLeft;

}
Offset thumbCenter = new Offset(trackActive, trackCenter);
_thumbPainter.paint(canvas,
Rect.fromCircle(center: thumbCenter, radius: CupertinoThumbPainter.radius));
new CupertinoThumbPainter(color: thumbColor).paint(canvas, Rect.fromCircle(center: thumbCenter, radius: CupertinoThumbPainter.radius));
}
}
}

453
com.unity.uiwidgets/Runtime/cupertino/switch.cs


public const float _kSwitchHeight = 39.0f;
public const float _kCupertinoSwitchDisabledOpacity = 0.5f;
public static readonly Color _kTrackColor = CupertinoColors.lightBackgroundGray;
public static readonly TimeSpan _kReactionDuration = new TimeSpan(0, 0, 0, 0, 300);
public static readonly TimeSpan _kToggleDuration = new TimeSpan(0, 0, 0, 0, 200);
public static readonly TimeSpan _kReactionDuration = TimeSpan.FromMilliseconds(300);
public static readonly TimeSpan _kToggleDuration = TimeSpan.FromMilliseconds(200);
}
public class CupertinoSwitch : StatefulWidget {

Key key = null,
Color activeColor = null,
Color trackColor = null,
this.trackColor = trackColor;
this.dragStartBehavior = dragStartBehavior;
}

public readonly Color activeColor;
public readonly Color trackColor;
public readonly DragStartBehavior dragStartBehavior;

}
class _CupertinoSwitchState : TickerProviderStateMixin<CupertinoSwitch> {
public TapGestureRecognizer _tap;
public HorizontalDragGestureRecognizer _drag;
AnimationController _positionController;
public CurvedAnimation position;
AnimationController _reactionController;
public Animation<float> _reaction;
bool isInteractive {
get {
return widget.onChanged != null;
}
}
bool needsPositionAnimation = false;
public override void initState() {
base.initState();
_tap = new TapGestureRecognizer();
_tap.onTapDown = _handleTapDown;
_tap.onTapUp = _handleTapUp;
_tap.onTap = _handleTap;
_tap.onTapCancel = _handleTapCancel;
_drag = new HorizontalDragGestureRecognizer();
_drag.onStart = _handleDragStart;
_drag.onUpdate = _handleDragUpdate;
_drag.onEnd = _handleDragEnd;
_drag.dragStartBehavior = widget.dragStartBehavior;
_positionController = new AnimationController(
duration: CupertinoSwitchUtils._kToggleDuration,
value: widget.value ? 1.0f : 0.0f,
vsync: this
);
position = new CurvedAnimation(
parent: _positionController,
curve: Curves.linear
);
_reactionController = new AnimationController(
duration: CupertinoSwitchUtils._kReactionDuration,
vsync: this
);
_reaction = new CurvedAnimation(
parent: _reactionController,
curve: Curves.ease
);
}
public override void didUpdateWidget(StatefulWidget oldWidget) {
oldWidget = (CupertinoSwitch) oldWidget;
base.didUpdateWidget(oldWidget);
_drag.dragStartBehavior = widget.dragStartBehavior;
if (needsPositionAnimation || ((CupertinoSwitch) oldWidget).value != widget.value)
_resumePositionAnimation(isLinear: needsPositionAnimation);
}
void _resumePositionAnimation( bool isLinear = true ) {
needsPositionAnimation = false;
position.curve = isLinear ? null : Curves.ease;
position.reverseCurve = isLinear ? null : Curves.ease.flipped;
if (widget.value)
_positionController.forward();
else
_positionController.reverse();
}
void _handleTapDown(TapDownDetails details) {
if (isInteractive)
needsPositionAnimation = false;
_reactionController.forward();
}
void _handleTap() {
if (isInteractive) {
widget.onChanged(!widget.value);
//_emitVibration();
}
}
void _handleTapUp(TapUpDetails details) {
if (isInteractive) {
needsPositionAnimation = false;
_reactionController.reverse();
}
}
void _handleTapCancel() {
if (isInteractive)
_reactionController.reverse();
}
void _handleDragStart(DragStartDetails details) {
if (isInteractive) {
needsPositionAnimation = false;
_reactionController.forward();
//_emitVibration();
}
}
void _handleDragUpdate(DragUpdateDetails details) {
if (isInteractive) {
position.curve = null;
position.reverseCurve = null;
float? delta = details.primaryDelta / CupertinoSwitchUtils._kTrackInnerLength;
switch (Directionality.of(context)) {
case TextDirection.rtl:
_positionController.setValue( _positionController.value - delta ?? 0.0f);
break;
case TextDirection.ltr:
_positionController.setValue( _positionController.value + delta ?? 0.0f);
break;
}
}
}
void _handleDragEnd(DragEndDetails details) {
setState(()=> { needsPositionAnimation = true; });
if (position.value >= 0.5 != widget.value)
widget.onChanged(!widget.value);
_reactionController.reverse();
}
if (needsPositionAnimation)
_resumePositionAnimation();
activeColor: widget.activeColor ?? CupertinoColors.activeGreen,
activeColor: CupertinoDynamicColor.resolve(
widget.activeColor ?? CupertinoColors.systemGreen,
context
),
trackColor: CupertinoDynamicColor.resolve(widget.trackColor ?? CupertinoColors.secondarySystemFill, context),
vsync: this,
dragStartBehavior: widget.dragStartBehavior
textDirection: Directionality.of(context),
state: this
public override void dispose() {
_tap.dispose();
_drag.dispose();
_positionController.dispose();
_reactionController.dispose();
base.dispose();
}
}
class _CupertinoSwitchRenderObjectWidget : LeafRenderObjectWidget {

Color activeColor = null,
Color trackColor = null,
TickerProvider vsync = null,
DragStartBehavior dragStartBehavior = DragStartBehavior.start
TextDirection? textDirection = null,
_CupertinoSwitchState state = null
this.trackColor = trackColor;
this.vsync = vsync;
this.dragStartBehavior = dragStartBehavior;
this.state = state;
this.textDirection = textDirection;
public readonly Color trackColor;
public readonly TickerProvider vsync;
public readonly DragStartBehavior dragStartBehavior;
public readonly _CupertinoSwitchState state;
public readonly TextDirection? textDirection;
trackColor: trackColor,
textDirection: Directionality.of(context),
vsync: vsync,
dragStartBehavior: dragStartBehavior
textDirection: textDirection,
state: state
);
}

_renderObject.activeColor = activeColor;
_renderObject.trackColor = trackColor;
_renderObject.textDirection = Directionality.of(context);
_renderObject.vsync = vsync;
_renderObject.dragStartBehavior = dragStartBehavior;
_renderObject.textDirection = textDirection;
}
}

bool value,
Color activeColor,
TextDirection textDirection,
TickerProvider vsync,
Color trackColor = null,
TextDirection? textDirection = null,
DragStartBehavior dragStartBehavior = DragStartBehavior.start
_CupertinoSwitchState state = null
D.assert(activeColor != null);
D.assert(vsync != null);
D.assert(state != null);
_trackColor = trackColor;
_vsync = vsync;
_tap = new TapGestureRecognizer() {
onTapDown = _handleTapDown,
onTap = _handleTap,
onTapUp = _handleTapUp,
onTapCancel = _handleTapCancel,
};
_drag = new HorizontalDragGestureRecognizer() {
onStart = _handleDragStart,
onUpdate = _handleDragUpdate,
onEnd = _handleDragEnd,
dragStartBehavior = dragStartBehavior
};
_state = state;
state.position.addListener(markNeedsPaint);
state._reaction.addListener(markNeedsPaint);
_positionController = new AnimationController(
duration: CupertinoSwitchUtils._kToggleDuration,
value: value ? 1.0f : 0.0f,
vsync: vsync
);
_position = new CurvedAnimation(
parent: _positionController,
curve: Curves.linear
);
_position.addListener(markNeedsPaint);
_position.addStatusListener(_handlePositionStateChanged);
_reactionController = new AnimationController(
duration: CupertinoSwitchUtils._kReactionDuration,
vsync: vsync
);
_reaction = new CurvedAnimation(
parent: _reactionController,
curve: Curves.ease
);
_reaction.addListener(markNeedsPaint);
}
AnimationController _positionController;

public readonly _CupertinoSwitchState _state;
if (value == _value) {
D.assert(value != null);
if (value == _value)
}
// this.markNeedsSemanticsUpdate();
_position.curve = Curves.ease;
_position.reverseCurve = Curves.ease.flipped;
if (value) {
_positionController.forward();
}
else {
_positionController.reverse();
}
//markNeedsSemanticsUpdate();
public TickerProvider vsync {
get { return _vsync; }
public Color activeColor {
get { return _activeColor; }
if (value == _vsync) {
if (value == _activeColor) {
_vsync = value;
_positionController.resync(vsync);
_reactionController.resync(vsync);
_activeColor = value;
markNeedsPaint();
TickerProvider _vsync;
Color _activeColor;
public Color activeColor {
get { return _activeColor; }
public Color trackColor {
get { return _trackColor; }
if (value == _activeColor) {
if (value == _trackColor)
}
_activeColor = value;
_trackColor = value;
Color _activeColor;
Color _trackColor;
public ValueChanged<bool> onChanged {
get { return _onChanged; }

ValueChanged<bool> _onChanged;
public TextDirection textDirection {
public TextDirection? textDirection {
get { return _textDirection; }
set {
if (_textDirection == value) {

}
}
TextDirection _textDirection;
public DragStartBehavior dragStartBehavior {
get { return _drag.dragStartBehavior; }
set {
if (_drag.dragStartBehavior == value) {
return;
}
_drag.dragStartBehavior = value;
}
}
TextDirection? _textDirection;
TapGestureRecognizer _tap;
HorizontalDragGestureRecognizer _drag;
public override void attach(object _owner) {
base.attach(_owner);
if (value) {
_positionController.forward();
}
else {
_positionController.reverse();
}
if (isInteractive) {
switch (_reactionController.status) {
case AnimationStatus.forward:
_reactionController.forward();
break;
case AnimationStatus.reverse:
_reactionController.reverse();
break;
case AnimationStatus.dismissed:
case AnimationStatus.completed:
break;
}
}
}
public override void detach() {
_positionController.stop();
_reactionController.stop();
base.detach();
}
void _handlePositionStateChanged(AnimationStatus status) {
if (isInteractive) {
if (status == AnimationStatus.completed && !_value) {
onChanged(true);
}
else if (status == AnimationStatus.dismissed && _value) {
onChanged(false);
}
}
}
void _handleTapDown(TapDownDetails details) {
if (isInteractive) {
_reactionController.forward();
}
}
void _handleTap() {
if (isInteractive) {
onChanged(!_value);
_emitVibration();
}
}
void _handleTapUp(TapUpDetails details) {
if (isInteractive) {
_reactionController.reverse();
}
}
void _handleTapCancel() {
if (isInteractive) {
_reactionController.reverse();
}
}
void _handleDragStart(DragStartDetails details) {
if (isInteractive) {
_reactionController.forward();
_emitVibration();
}
}
void _handleDragUpdate(DragUpdateDetails details) {
if (isInteractive) {
_position.curve = null;
_position.reverseCurve = null;
float delta = details.primaryDelta / CupertinoSwitchUtils._kTrackInnerLength ?? 0f;
_positionController.setValue(_positionController.value + delta);
// switch (this.textDirection) {
// case TextDirection.rtl:
// this._positionController.setValue(this._positionController.value - delta);
// break;
// case TextDirection.ltr:
// this._positionController.setValue(this._positionController.value + delta);
// break;
// }
}
}
void _handleDragEnd(DragEndDetails details) {
if (_position.value >= 0.5) {
_positionController.forward();
}
else {
_positionController.reverse();
}
_reactionController.reverse();
}
void _emitVibration() {
// switch (Platform defaultTargetPlatform) {
// case TargetPlatform.iOS:
// HapticFeedback.lightImpact();
// break;
// case TargetPlatform.fuchsia:
// case TargetPlatform.android:
// break;
// }
return;
}
protected override bool hitTestSelf(Offset position) {
return true;
}

if (evt is PointerDownEvent && isInteractive) {
_drag.addPointer(evt as PointerDownEvent);
_tap.addPointer(evt as PointerDownEvent);
_state._drag.addPointer((PointerDownEvent) evt);
_state._tap.addPointer((PointerDownEvent) evt);
// public override void describeSemanticsConfiguration(SemanticsConfiguration config) {
// base.describeSemanticsConfiguration(config);
//
// if (isInteractive)
// config.onTap = _handleTap;
//
// config.isEnabled = isInteractive;
// config.isToggled = _value;
// }
public readonly CupertinoThumbPainter _thumbPainter = new CupertinoThumbPainter();
float currentValue = _state.position.value;
float currentReactionValue = _state._reaction.value;
float currentValue = _position.value;
float currentReactionValue = _reaction.value;
float visualPosition = 0f;
float visualPosition = 0.0f;
switch (textDirection) {
case TextDirection.rtl:
visualPosition = 1.0f - currentValue;

break;
}
Color trackColor = _value ? activeColor : CupertinoSwitchUtils._kTrackColor;
float borderThickness =
1.5f + (CupertinoSwitchUtils._kTrackRadius - 1.5f) * Mathf.Max(currentReactionValue, currentValue);
Paint paint = new Paint();
paint.color = trackColor;
Paint paint = new Paint() {color = Color.lerp(trackColor, activeColor, currentValue)};
Rect trackRect = Rect.fromLTWH(
offset.dx + (size.width - CupertinoSwitchUtils._kTrackWidth) / 2.0f,
offset.dy + (size.height - CupertinoSwitchUtils._kTrackHeight) / 2.0f,

RRect outerRRect = RRect.fromRectAndRadius(trackRect, Radius.circular(CupertinoSwitchUtils
._kTrackRadius));
RRect innerRRect = RRect.fromRectAndRadius(trackRect.deflate(borderThickness), Radius.circular
(CupertinoSwitchUtils._kTrackRadius));
canvas.drawDRRect(outerRRect, innerRRect, paint);
RRect trackRRect = RRect.fromRectAndRadius(trackRect, Radius.circular(CupertinoSwitchUtils._kTrackRadius));
canvas.drawRRect(trackRRect, paint);
float currentThumbExtension = CupertinoThumbPainter.extension * currentReactionValue;
float thumbLeft = MathUtils.lerpFloat(

visualPosition
);
float thumbCenterY = offset.dy + size.height / 2.0f;
_thumbPainter.paint(canvas, Rect.fromLTRB(
Rect thumbBounds = Rect.fromLTRB(
));
}
);
context.pushClipRRect(needsCompositing, Offset.zero, thumbBounds, trackRRect,
(PaintingContext innerContext, Offset offset) => {
CupertinoThumbPainter.switchThumb().paint(innerContext.canvas, thumbBounds);
});
}
public override void debugFillProperties(DiagnosticPropertiesBuilder description) {
base.debugFillProperties(description);

ifFalse: "disabled",
showName: true, defaultValue: true));
}
}
}

63
com.unity.uiwidgets/Runtime/cupertino/tab_scaffold.cs


public class CupertinoTabController : ChangeNotifier {
public CupertinoTabController(int initialIndex = 0) {
_index = initialIndex;
_index = initialIndex;
}
public bool _isDisposed = false;

D.assert(tabBuilder != null);
D.assert(
controller == null || controller.index < tabBar.items.Count, () =>
"The CupertinoTabController's current index ${controller.index} is " +
"out of bounds for the tab bar with ${tabBar.items.length} tabs"
$"The CupertinoTabController's current index {controller.index} is " +
$"out of bounds for the tab bar with {tabBar.items.Count} tabs"
);
this.tabBar = tabBar;
this.controller = controller;

public override void initState() {
base.initState();
//_currentPage = widget.tabBar.currentIndex;
_updateTabController();
}
void _updateTabController( bool shouldDisposeOldController = false ) {

void _onCurrentIndexChange() {
D.assert(
_controller.index >= 0 && _controller.index < widget.tabBar.items.Count,()=>
"The $runtimeType's current index ${_controller.index} is " +
$"The {GetType()}'s current index {_controller.index} is " +
$"out of bounds for the tab bar with {widget.tabBar.items.Count} tabs"
);
setState(()=> {});

_controller.index = widget.tabBar.items.Count - 1;
}
}
/*public override void didUpdateWidget(StatefulWidget _oldWidget) {
CupertinoTabScaffold oldWidget = _oldWidget as CupertinoTabScaffold;
base.didUpdateWidget(oldWidget);
if (_currentPage >= widget.tabBar.items.Count) {
_currentPage = widget.tabBar.items.Count - 1;
D.assert(_currentPage >= 0,
() => "CupertinoTabBar is expected to keep at least 2 tabs after updating"
);
}
if (widget.tabBar.currentIndex != oldWidget.tabBar.currentIndex) {
_currentPage = widget.tabBar.currentIndex;
}
}*/
public override Widget build(BuildContext context) {
List<Widget> stacked = new List<Widget> { };

/*Widget content = new _TabSwitchingView(
currentTabIndex: _currentPage,
tabNumber: widget.tabBar.items.Count,
tabBuilder: widget.tabBuilder
);*/
Widget content = new _TabSwitchingView(
currentTabIndex: _controller.index,
tabNumber: widget.tabBar.items.Count,

child: content
)
);
/*if (widget.tabBar != null) {
stacked.Add(new Align(
alignment: Alignment.bottomCenter,
child: widget.tabBar.copyWith(
currentIndex: _currentPage,
onTap: (int newIndex) => {
setState(() => { _currentPage = newIndex; });
if (widget.tabBar.onTap != null) {
widget.tabBar.onTap(newIndex);
}
}
)
));
}*/
stacked.Add(
new MediaQuery(
data: existingMediaQuery.copyWith(textScaleFactor: 1),

decoration: new BoxDecoration(
color: CupertinoDynamicColor.resolve(widget.backgroundColor, context)
?? CupertinoTheme.of(context).scaffoldBackgroundColor
//color: widget.backgroundColor ?? CupertinoTheme.of(context).scaffoldBackgroundColor
),
child: new Stack(
children: stacked

public override void dispose() {
// Only dispose `_controller` when the state instance owns it.
if (widget.controller == null) {
_controller?.dispose();
} else if (_controller?._isDisposed == false) {

base.dispose();
base.dispose();
}
}

}
class _TabSwitchingViewState : State<_TabSwitchingView> {
//List<Widget> tabs;
public readonly List<bool> shouldBuildTab = new List<bool>();
public readonly List<FocusScopeNode> tabFocusNodes = new List<FocusScopeNode>();
public readonly List<FocusScopeNode> discardedNodes = new List<FocusScopeNode>();

for (int i = widget.tabNumber; i < shouldBuildTab.Count; i++) {
shouldBuildTab.RemoveAt(i);
}
;
}
_focusActiveTab();
}

}
else {
tabFocusNodes.Add(new FocusScopeNode());
tabFocusNodes.Add(new FocusScopeNode(debugLabel: $"CupertinoTabScaffold Tab {i + tabFocusNodes.Count}")
);
}
}

foreach(FocusScopeNode focusScopeNode in tabFocusNodes) {
focusScopeNode.dispose();
}
foreach( FocusScopeNode focusScopeNode in discardedNodes) {
focusScopeNode.dispose();
}
List<Widget> stages = new List<Widget>();
int count = widget.tabNumber;
for (int i = 0; i < count; i++) {

2
com.unity.uiwidgets/Runtime/cupertino/tab_view.cs


}
public override void didUpdateWidget(StatefulWidget oldWidget) {
base.didUpdateWidget(oldWidget);
base.didUpdateWidget(oldWidget);
if (widget.navigatorKey != _oldWidget.navigatorKey
|| widget.navigatorObservers != _oldWidget.navigatorObservers) {
_updateObservers();

682
com.unity.uiwidgets/Runtime/cupertino/text_selection.cs


namespace Unity.UIWidgets.cupertino {
public static class CupertinoTextSelectionUtils {
public static readonly TextSelectionControls cupertinoTextSelectionControls = new _CupertinoTextSelectionControls();
// public static readonly TextSelectionControls cupertinoTextSelectionControls = new _CupertinoTextSelectionControls();
public const float _kSelectionHandleOverlap = 1.5f;

public const float _kToolbarHeight = 43.0f;
public static readonly Size _kToolbarArrowSize = new Size(14.0f, 7.0f);
//public static readonly Radius _kToolbarBorderRadius = Radius.circular(8);
public static readonly BorderRadius _kToolbarBorderRadius = BorderRadius.all(Radius.circular(7.5f));
public static readonly Radius _kToolbarBorderRadius = Radius.circular(8);
public static readonly Color _kToolbarBackgroundColor = new Color(0xFF2E2E2E);
public static readonly Color _kToolbarDividerColor = new Color(0xFFB9B9B9);
public static readonly Color _kToolbarBackgroundColor = new Color(0xEB202020);
public static readonly Color _kToolbarDividerColor = new Color(0xFF808080);
public static readonly Color _kHandlesColor = new Color(0xFF136FE0);

public static readonly EdgeInsets _kToolbarButtonPadding =
EdgeInsets.symmetric(vertical: 10.0f, horizontal: 18.0f);
//public static readonly BorderRadius _kToolbarBorderRadius = BorderRadius.all(Radius.circular(7.5f));
inherit: false,
fontSize: 14.0f,
letterSpacing: -0.15f,
fontWeight: FontWeight.w400,

/* class CupertinoTextSelectionToolbar : SingleChildRenderObjectWidget {
class CupertinoTextSelectionToolbar : SingleChildRenderObjectWidget {
public CupertinoTextSelectionToolbar(
Key key = null,
float barTopY = 0.0f,

public override string ToString() => $"offset = {offset}," + $"arrowXOffsetFromCenter={arrowXOffsetFromCenter}";
}
class _ToolbarRenderBox : RenderShiftedBox {
public _ToolbarRenderBox(
float _barTopY = 0.0f,
float _arrowTipX = 0.0f,
bool _isArrowPointingDown = false,
RenderBox child = null
) : base(child) {
this._barTopY = _barTopY;
this._arrowTipX = _arrowTipX;
this._isArrowPointingDown = _isArrowPointingDown;
}
class _ToolbarRenderBox : RenderShiftedBox {
public _ToolbarRenderBox(
float _barTopY = 0.0f,
float _arrowTipX = 0.0f,
bool _isArrowPointingDown = false,
RenderBox child = null) : base(child) {
this._barTopY = _barTopY;
this._arrowTipX = _arrowTipX;
this._isArrowPointingDown = _isArrowPointingDown;
}
public override bool isRepaintBoundary {
public override bool isRepaintBoundary {
get { return true; }
}

child.parentData = new _ToolbarParentData();
}
}
protected override void performLayout() {
BoxConstraints constraints = this.constraints;
size = constraints.biggest;

child.layout(heightConstraint.enforce(enforcedConstraint), parentUsesSize: true);
_ToolbarParentData childParentData = child.parentData as _ToolbarParentData;
// The local x-coordinate of the center of the toolbar.
childParentData.offset = new Offset(adjustedCenterX - child.size.width / 2, _barTopY);
childParentData.arrowXOffsetFromCenter = _arrowTipX - adjustedCenterX;
childParentData.offset = new Offset(adjustedCenterX - child.size.width / 2, _barTopY );
childParentData.arrowXOffsetFromCenter = _arrowTipX - adjustedCenterX ;
_ToolbarParentData childParentData = child.parentData as _ToolbarParentData;
Path rrect = new Path();
rrect.addRRect(
RRect.fromRectAndRadius(
new Offset(0, _isArrowPointingDown ? 0 : CupertinoTextSelectionUtils._kToolbarArrowSize.height)
& new Size(child.size.width, child.size.height - CupertinoTextSelectionUtils._kToolbarArrowSize.height),
CupertinoTextSelectionUtils._kToolbarBorderRadius
));
_ToolbarParentData childParentData = child.parentData as _ToolbarParentData;
Path rrect = new Path();
rrect.addRRect(
RRect.fromRectAndRadius(
new Offset(0, _isArrowPointingDown ? 0 : CupertinoTextSelectionUtils._kToolbarArrowSize.height)
& new Size(child.size.width, child.size.height - CupertinoTextSelectionUtils._kToolbarArrowSize.height),
CupertinoTextSelectionUtils._kToolbarBorderRadius
));
float arrowTipX = child.size.width / 2 + childParentData.arrowXOffsetFromCenter;
float arrowTipX = child.size.width / 2 + childParentData.arrowXOffsetFromCenter;
float arrowBottomY = _isArrowPointingDown
? child.size.height - CupertinoTextSelectionUtils._kToolbarArrowSize.height
: CupertinoTextSelectionUtils._kToolbarArrowSize.height;
float arrowBottomY = _isArrowPointingDown
? child.size.height - CupertinoTextSelectionUtils._kToolbarArrowSize.height
: CupertinoTextSelectionUtils._kToolbarArrowSize.height;
float arrowTipY = _isArrowPointingDown ? child.size.height : 0;
float arrowTipY = _isArrowPointingDown ? child.size.height : 0;
Path arrow = new Path();
arrow.moveTo(arrowTipX, arrowTipY);
arrow.lineTo(arrowTipX - CupertinoTextSelectionUtils._kToolbarArrowSize.width / 2, arrowBottomY);
arrow.lineTo(arrowTipX + CupertinoTextSelectionUtils._kToolbarArrowSize.width / 2, arrowBottomY);
arrow.close();
Path arrow = new Path();
arrow.moveTo(arrowTipX, arrowTipY);
arrow.lineTo(arrowTipX - CupertinoTextSelectionUtils._kToolbarArrowSize.width / 2, arrowBottomY);
arrow.lineTo(arrowTipX + CupertinoTextSelectionUtils._kToolbarArrowSize.width / 2, arrowBottomY);
arrow.close();
return Path.combine(PathOperation.union, rrect, arrow);
return Path.combine(PathOperation.union, rrect, arrow);
if (child == null) {
return;
}
if (child == null) {
return;
}
_ToolbarParentData childParentData = child.parentData as _ToolbarParentData;
context.pushClipPath(
needsCompositing,
offset + childParentData.offset,
Offset.zero & child.size,
_clipPath(),
(PaintingContext innerContext, Offset innerOffset) => innerContext.paintChild(child, innerOffset),
);
_ToolbarParentData childParentData = child.parentData as _ToolbarParentData;
context.pushClipPath(
needsCompositing,
offset + childParentData.offset,
Offset.zero & child.size,
_clipPath(),
(PaintingContext innerContext, Offset innerOffset) => innerContext.paintChild(child, innerOffset)
);
}
Paint _debugPaint;

D.assert(() => {
if (child == null) {
D.assert(() => {
if (child == null) {
return true;
}
//_debugPaint ??= new Paint()
if (_debugPaint == null) {
_debugPaint = new Paint();
}
_debugPaint.shader = ui.Gradient.linear(
new Offset(0.0f, 0.0f),
new Offset(10.0f, 10.0f),
new List<Color> {
new Color(0x00000000), new Color(0xFFFF00FF), new Color(0xFFFF00FF),
new Color(0x00000000)
},
new List<float> {0.25f, 0.25f, 0.75f, 0.75f},
TileMode.repeated
);
_debugPaint.strokeWidth = 2.0f;
_debugPaint.style = PaintingStyle.stroke;
_ToolbarParentData childParentData = child.parentData as _ToolbarParentData;
context.canvas.drawPath(_clipPath().shift(offset + childParentData.offset), _debugPaint);
});
//_debugPaint ??= new Paint()
if (_debugPaint == null) {
_debugPaint = new Paint();
}
_debugPaint.shader = ui.Gradient.linear(
new Offset(0.0f, 0.0f),
new Offset(10.0f, 10.0f),
new List<Color> {
new Color(0x00000000), new Color(0xFFFF00FF), new Color(0xFFFF00FF),
new Color(0x00000000)
},
new List<float> {0.25f, 0.25f, 0.75f, 0.75f},
TileMode.repeated
);
_debugPaint.strokeWidth = 2.0f;
_debugPaint.style = PaintingStyle.stroke;
_ToolbarParentData childParentData = child.parentData as _ToolbarParentData;
context.canvas.drawPath(_clipPath().shift(offset + childParentData.offset), _debugPaint);
return true;
});
}
/// Draws a single text selection handle with a bar and a ball.
public class _TextSelectionHandlePainter : CustomPainter {
public class _TextSelectionHandlePainter : AbstractCustomPainter {
public _TextSelectionHandlePainter(Color color) {
this.color = color;
}

oldPainter = (_TextSelectionHandlePainter)oldPainter;
return color != ((_TextSelectionHandlePainter)oldPainter).color;
}
public bool? hitTest(Offset position) {
return null;
}
public void addListener(VoidCallback listener) {
base.addListener(listener);
}
public void removeListener(VoidCallback listener) {
base.removeListener(listener);
}
public delegate bool Predicate(TextSelectionDelegate _delegate);
public delegate void OnPressed(TextSelectionDelegate _delegate);
/// Returns the size of the Cupertino handle.
public override Size getHandleSize(float textLineHeight) {
return new Size(
CupertinoTextSelectionUtils._kSelectionHandleRadius * 2,
textLineHeight + CupertinoTextSelectionUtils._kSelectionHandleRadius * 2 - CupertinoTextSelectionUtils._kSelectionHandleOverlap
);
}
public new Widget buildToolbar(
BuildContext context,
Rect globalEditableRegion,
float textLineHeight,
Offset position,
List<TextSelectionPoint> endpoints
//TextSelectionDelegate delegate
)
{
D.assert(debugCheckHasMediaQuery(context));
MediaQueryData mediaQuery = MediaQuery.of(context);
float toolbarHeightNeeded = mediaQuery.padding.top
+ CupertinoTextSelectionUtils._kToolbarScreenPadding
+ CupertinoTextSelectionUtils._kToolbarHeight
+ CupertinoTextSelectionUtils._kToolbarContentDistance;
float availableHeight = globalEditableRegion.top + endpoints.first().point.dy - textLineHeight;
bool isArrowPointingDown = toolbarHeightNeeded <= availableHeight;
public override Size getHandleSize(float textLineHeight) {
return new Size(
CupertinoTextSelectionUtils._kSelectionHandleRadius * 2,
textLineHeight + CupertinoTextSelectionUtils._kSelectionHandleRadius * 2 - CupertinoTextSelectionUtils._kSelectionHandleOverlap
);
}
public override Widget buildToolbar(
BuildContext context,
Rect globalEditableRegion,
float textLineHeight,
Offset position,
List<TextSelectionPoint> endpoints,
TextSelectionDelegate _delegate
)
{
D.assert(WidgetsD.debugCheckHasMediaQuery(context));
MediaQueryData mediaQuery = MediaQuery.of(context);
float arrowTipX = (position.dx + globalEditableRegion.left).clamp(
CupertinoTextSelectionUtils._kArrowScreenPadding + mediaQuery.padding.left,
mediaQuery.size.width - mediaQuery.padding.right - CupertinoTextSelectionUtils._kArrowScreenPadding
) ;
float localBarTopY = isArrowPointingDown
? endpoints.first().point.dy - textLineHeight - CupertinoTextSelectionUtils._kToolbarContentDistance - CupertinoTextSelectionUtils._kToolbarHeight
: endpoints.last().point.dy + CupertinoTextSelectionUtils._kToolbarContentDistance;
List<Widget> items = new List<Widget>{};
Widget onePhysicalPixelVerticalDivider =
new SizedBox(width: 1.0f / MediaQuery.of(context).devicePixelRatio);
CupertinoLocalizations localizations = CupertinoLocalizations.of(context);
EdgeInsets arrowPadding = isArrowPointingDown
? EdgeInsets.only(bottom: CupertinoTextSelectionUtils._kToolbarArrowSize.height)
: EdgeInsets.only(top: CupertinoTextSelectionUtils._kToolbarArrowSize.height);
float toolbarHeightNeeded = mediaQuery.padding.top
+ CupertinoTextSelectionUtils._kToolbarScreenPadding
+ CupertinoTextSelectionUtils._kToolbarHeight
+ CupertinoTextSelectionUtils._kToolbarContentDistance;
float availableHeight = globalEditableRegion.top + endpoints.first().point.dy - textLineHeight;
bool isArrowPointingDown = toolbarHeightNeeded <= availableHeight;
void addToolbarButtonIfNeeded(
string text,
bool Function(TextSelectionDelegate) predicate,
void Function(TextSelectionDelegate) onPressed) {
if (!predicate(delegate)) {
return;
}
if (items.isNotEmpty()) {
items.Add(onePhysicalPixelVerticalDivider);
}
float arrowTipX = (position.dx + globalEditableRegion.left).clamp(
CupertinoTextSelectionUtils._kArrowScreenPadding + mediaQuery.padding.left,
mediaQuery.size.width - mediaQuery.padding.right - CupertinoTextSelectionUtils._kArrowScreenPadding
) ;
float localBarTopY = isArrowPointingDown
? endpoints.first().point.dy - textLineHeight - CupertinoTextSelectionUtils._kToolbarContentDistance - CupertinoTextSelectionUtils._kToolbarHeight
: endpoints.last().point.dy + CupertinoTextSelectionUtils._kToolbarContentDistance;
items.Add(new CupertinoButton(
child: new Text(text, style:CupertinoTextSelectionUtils. _kToolbarButtonFontStyle),
color: CupertinoTextSelectionUtils._kToolbarBackgroundColor,
minSize: CupertinoTextSelectionUtils._kToolbarHeight,
padding: CupertinoTextSelectionUtils._kToolbarButtonPadding.add(arrowPadding),
borderRadius: null,
pressedOpacity: 0.7f,
onPressed: () => onPressed(delegate)
));
}
List<Widget> items = new List<Widget>{};
Widget onePhysicalPixelVerticalDivider = new SizedBox(width: 1.0f / MediaQuery.of(context).devicePixelRatio);
CupertinoLocalizations localizations = CupertinoLocalizations.of(context);
EdgeInsets arrowPadding = isArrowPointingDown
? EdgeInsets.only(bottom: CupertinoTextSelectionUtils._kToolbarArrowSize.height)
: EdgeInsets.only(top: CupertinoTextSelectionUtils._kToolbarArrowSize.height);
void addToolbarButtonIfNeeded(
string text,
Predicate predicate,
OnPressed onPressed) {
if (!predicate(_delegate)) {
return;
}
addToolbarButtonIfNeeded(localizations.cutButtonLabel, canCut, handleCut);
addToolbarButtonIfNeeded(localizations.copyButtonLabel, canCopy, handleCopy);
addToolbarButtonIfNeeded(localizations.pasteButtonLabel, canPaste, handlePaste);
addToolbarButtonIfNeeded(localizations.selectAllButtonLabel, canSelectAll, handleSelectAll);
if (items.isNotEmpty()) {
items.Add(onePhysicalPixelVerticalDivider);
}
return new CupertinoTextSelectionToolbar(
barTopY: localBarTopY + globalEditableRegion.top,
arrowTipX: arrowTipX,
isArrowPointingDown: isArrowPointingDown,
child: items.isEmpty() ? null : new DecoratedBox(
decoration: new BoxDecoration(color: CupertinoTextSelectionUtils._kToolbarDividerColor),
child: new Row(mainAxisSize: MainAxisSize.min, children: items)
)
);
items.Add(new CupertinoButton(
child: new Text(text, style:CupertinoTextSelectionUtils. _kToolbarButtonFontStyle),
color: CupertinoTextSelectionUtils._kToolbarBackgroundColor,
minSize: CupertinoTextSelectionUtils._kToolbarHeight,
padding: CupertinoTextSelectionUtils._kToolbarButtonPadding.add(arrowPadding),
borderRadius: null,
pressedOpacity: 0.7f,
onPressed: () => onPressed(_delegate)
));
}
addToolbarButtonIfNeeded(localizations.cutButtonLabel, canCut, handleCut);
addToolbarButtonIfNeeded(localizations.copyButtonLabel, canCopy, handleCopy);
addToolbarButtonIfNeeded(localizations.pasteButtonLabel, canPaste, handlePaste);
addToolbarButtonIfNeeded(localizations.selectAllButtonLabel, canSelectAll, handleSelectAll);
return new CupertinoTextSelectionToolbar(
barTopY: localBarTopY + globalEditableRegion.top,
arrowTipX: arrowTipX,
isArrowPointingDown: isArrowPointingDown,
child: items.isEmpty() ? null : new DecoratedBox(
decoration: new BoxDecoration(color: CupertinoTextSelectionUtils._kToolbarDividerColor),
child: new Row(mainAxisSize: MainAxisSize.min, children: items)
)
);
size: desiredSize,
child: new CustomPaint(
painter: new _TextSelectionHandlePainter(CupertinoTheme.of(context).primaryColor)
)
);
switch (type) {
case TextSelectionHandleType.left:
return handle;
case TextSelectionHandleType.right:
// Right handle is a vertical mirror of the left.
return new Transform(
transform: Matrix4.identity()
..translate(desiredSize.width / 2, desiredSize.height / 2)
..rotateZ(math.pi)
..translate(-desiredSize.width / 2, -desiredSize.height / 2),
child: handle
);
// iOS doesn't draw anything for collapsed selections.
case TextSelectionHandleType.collapsed:
return new SizedBox();
size: desiredSize,
child: new CustomPaint(
painter: new _TextSelectionHandlePainter(CupertinoTheme.of(context).primaryColor)
)
);
var result = Matrix4.identity();
result.translate(desiredSize.width / 2, desiredSize.height / 2);
result.rotateZ(Mathf.PI);
result.translate(-desiredSize.width / 2, -desiredSize.height / 2);
switch (type) {
case TextSelectionHandleType.left:
return handle;
case TextSelectionHandleType.right:
return new Transform(
transform: result,
child: handle
);
case TextSelectionHandleType.collapsed:
return new SizedBox();
}
D.assert(type != null);
return null;
D.assert(type != null);
return null;
}
public override Offset getHandleAnchor(TextSelectionHandleType type, float textLineHeight) {
public override Offset getHandleAnchor(TextSelectionHandleType type, float textLineHeight) {
// The circle is at the top for the left handle, and the anchor point is
// all the way at the bottom of the line.
// The right handle is vertically flipped, and the anchor point is near
// the top of the circle to give slight overlap.
// A collapsed handle anchors itself so that it's centered.
default:
return new Offset(
handleSize.width / 2,

}
}*/
/// Text selection controls that follows iOS design conventions.
class _TextSelectionToolbarNotchPainter : AbstractCustomPainter {
public override void paint(Canvas canvas, Size size) {
Paint paint = new Paint();
paint.color = CupertinoTextSelectionUtils._kToolbarBackgroundColor;
paint.style = PaintingStyle.fill;
Path triangle = new Path();
triangle.lineTo(CupertinoTextSelectionUtils._kToolbarTriangleSize.width / 2, 0.0f);
triangle.lineTo(0.0f, CupertinoTextSelectionUtils._kToolbarTriangleSize.height);
triangle.lineTo(-(CupertinoTextSelectionUtils._kToolbarTriangleSize.width / 2), 0.0f);
triangle.close();
canvas.drawPath(triangle, paint);
}
public override bool shouldRepaint(CustomPainter oldPainter) {
return false;
}
class _TextSelectionToolbar : StatelessWidget {
public _TextSelectionToolbar(
Key key = null,
VoidCallback handleCut = null,
VoidCallback handleCopy = null,
VoidCallback handlePaste = null,
VoidCallback handleSelectAll = null
) : base(key: key) {
this.handleCut = handleCut;
this.handleCopy = handleCopy;
this.handlePaste = handlePaste;
this.handleSelectAll = handleSelectAll;
}
readonly VoidCallback handleCut;
readonly VoidCallback handleCopy;
readonly VoidCallback handlePaste;
readonly VoidCallback handleSelectAll;
public override Widget build(BuildContext context) {
List<Widget> items = new List<Widget>();
Widget onePhysicalPixelVerticalDivider =
new SizedBox(width: 1.0f / MediaQuery.of(context).devicePixelRatio);
CupertinoLocalizations localizations = CupertinoLocalizations.of(context);
if (handleCut != null) {
items.Add(_buildToolbarButton(localizations.cutButtonLabel, handleCut));
}
if (handleCopy != null) {
if (items.isNotEmpty()) {
items.Add(onePhysicalPixelVerticalDivider);
}
items.Add(_buildToolbarButton(localizations.copyButtonLabel, handleCopy));
}
if (handlePaste != null) {
if (items.isNotEmpty()) {
items.Add(onePhysicalPixelVerticalDivider);
}
items.Add(_buildToolbarButton(localizations.pasteButtonLabel, handlePaste));
}
if (handleSelectAll != null) {
if (items.isNotEmpty()) {
items.Add(onePhysicalPixelVerticalDivider);
}
items.Add(_buildToolbarButton(localizations.selectAllButtonLabel, handleSelectAll));
}
Widget triangle = SizedBox.fromSize(
size: CupertinoTextSelectionUtils._kToolbarTriangleSize,
child: new CustomPaint(
painter: new _TextSelectionToolbarNotchPainter()
)
);
return new Column(
mainAxisSize: MainAxisSize.min,
children: new List<Widget> {
new ClipRRect(
borderRadius: CupertinoTextSelectionUtils._kToolbarBorderRadius,
child: new DecoratedBox(
decoration: new BoxDecoration(
color: CupertinoTextSelectionUtils._kToolbarDividerColor,
borderRadius: CupertinoTextSelectionUtils._kToolbarBorderRadius,
border: Border.all(color: CupertinoTextSelectionUtils._kToolbarBackgroundColor,
width: 0)
),
child: new Row(mainAxisSize: MainAxisSize.min, children: items)
)
),
triangle,
new Padding(padding: EdgeInsets.only(bottom: 10.0f))
}
);
}
CupertinoButton _buildToolbarButton(string text, VoidCallback onPressed) {
return new CupertinoButton(
child: new Text(text, style: CupertinoTextSelectionUtils._kToolbarButtonFontStyle),
color: CupertinoTextSelectionUtils._kToolbarBackgroundColor,
minSize: CupertinoTextSelectionUtils._kToolbarHeight,
padding: CupertinoTextSelectionUtils._kToolbarButtonPadding,
borderRadius: null,
pressedOpacity: 0.7f,
onPressed: onPressed
);
}
}
class _TextSelectionToolbarLayout : SingleChildLayoutDelegate {
public _TextSelectionToolbarLayout(
Size screenSize,
Rect globalEditableRegion,
Offset position) {
this.screenSize = screenSize;
this.globalEditableRegion = globalEditableRegion;
this.position = position;
}
readonly Size screenSize;
readonly Rect globalEditableRegion;
readonly Offset position;
public override BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
return constraints.loosen();
}
public override Offset getPositionForChild(Size size, Size childSize) {
Offset globalPosition = globalEditableRegion.topLeft + position;
float x = globalPosition.dx - childSize.width / 2.0f;
float y = globalPosition.dy - childSize.height;
if (x < CupertinoTextSelectionUtils._kToolbarScreenPadding) {
x = CupertinoTextSelectionUtils._kToolbarScreenPadding;
}
else if (x + childSize.width > screenSize.width - CupertinoTextSelectionUtils._kToolbarScreenPadding) {
x = screenSize.width - childSize.width - CupertinoTextSelectionUtils._kToolbarScreenPadding;
}
if (y < CupertinoTextSelectionUtils._kToolbarScreenPadding) {
y = CupertinoTextSelectionUtils._kToolbarScreenPadding;
}
else if (y + childSize.height >
screenSize.height - CupertinoTextSelectionUtils._kToolbarScreenPadding) {
y = screenSize.height - childSize.height - CupertinoTextSelectionUtils._kToolbarScreenPadding;
}
return new Offset(x, y);
}
public override bool shouldRelayout(SingleChildLayoutDelegate oldDelegate) {
_TextSelectionToolbarLayout _oldDelegate = (_TextSelectionToolbarLayout) oldDelegate;
return screenSize != _oldDelegate.screenSize
|| globalEditableRegion != _oldDelegate.globalEditableRegion
|| position != _oldDelegate.position;
}
}
class _TextSelectionHandlePainter : AbstractCustomPainter {
public _TextSelectionHandlePainter(Offset origin) {
this.origin = origin;
}
readonly Offset origin;
public override void paint(Canvas canvas, Size size) {
Paint paint = new Paint();
paint.color = CupertinoTextSelectionUtils._kHandlesColor;
paint.strokeWidth = 2.0f;
canvas.drawCircle(origin.translate(0.0f, 4.0f), 5.5f, paint);
canvas.drawLine(
origin,
origin.translate(
0.0f,
-(size.height - 2.0f * CupertinoTextSelectionUtils._kHandlesPadding)
),
paint
);
}
public override bool shouldRepaint(CustomPainter oldPainter) {
_TextSelectionHandlePainter _oldPainter = (_TextSelectionHandlePainter) oldPainter;
return origin != _oldPainter.origin;
}
}
class _CupertinoTextSelectionControls : TextSelectionControls {
public override Size getHandleSize(float textLineHeight) {
return new Size(
CupertinoTextSelectionUtils._kSelectionHandleRadius * 2,
textLineHeight + CupertinoTextSelectionUtils._kSelectionHandleRadius * 2 -
CupertinoTextSelectionUtils._kSelectionHandleOverlap
);
}
public override Offset getHandleAnchor(TextSelectionHandleType type, float textLineHeight) {
Size handleSize = getHandleSize(textLineHeight);
switch (type) {
case TextSelectionHandleType.left:
return new Offset(
handleSize.width / 2,
handleSize.height
);
case TextSelectionHandleType.right:
return new Offset(
handleSize.width / 2,
handleSize.height - 2 * CupertinoTextSelectionUtils._kSelectionHandleRadius + CupertinoTextSelectionUtils._kSelectionHandleOverlap
);
default:
return new Offset(
handleSize.width / 2,
textLineHeight + (handleSize.height - textLineHeight) / 2
);
}
}
public override Widget buildToolbar(
BuildContext context,
Rect globalEditableRegion,
float textLineHeight,
Offset position,
List<TextSelectionPoint> endpoints,
TextSelectionDelegate del) {
D.assert(WidgetsD.debugCheckHasMediaQuery(context));
return new ConstrainedBox(
constraints: BoxConstraints.tight(globalEditableRegion.size),
child: new CustomSingleChildLayout(
layoutDelegate: new _TextSelectionToolbarLayout(
MediaQuery.of(context).size,
globalEditableRegion,
position
),
child: new _TextSelectionToolbar(
handleCut: canCut(del) ? () => handleCut(del) : (VoidCallback) null,
handleCopy: canCopy(del) ? () => handleCopy(del) : (VoidCallback) null,
handlePaste: canPaste(del) ? () => handlePaste(del) : (VoidCallback) null,
handleSelectAll: canSelectAll(del) ? () => handleSelectAll(del) : (VoidCallback) null
)
)
);
}
public override Widget buildHandle(BuildContext context, TextSelectionHandleType type, float textLineHeight) {
Size desiredSize = new Size(
2.0f * CupertinoTextSelectionUtils._kHandlesPadding,
textLineHeight + 2.0f * CupertinoTextSelectionUtils._kHandlesPadding
);
Widget handle = SizedBox.fromSize(
size: desiredSize,
child: new CustomPaint(
painter: new _TextSelectionHandlePainter(
origin: new Offset(CupertinoTextSelectionUtils._kHandlesPadding,
textLineHeight + CupertinoTextSelectionUtils._kHandlesPadding)
)
)
);
switch (type) {
case TextSelectionHandleType.left:
Matrix4 matrix = Matrix4.rotationZ(Mathf.PI);
matrix.translate(-CupertinoTextSelectionUtils._kHandlesPadding,
-CupertinoTextSelectionUtils._kHandlesPadding);
return new Transform(
transform: matrix,
child: handle
);
case TextSelectionHandleType.right:
return new Transform(
transform:Matrix4.translationValues(
-CupertinoTextSelectionUtils._kHandlesPadding,
-(textLineHeight + CupertinoTextSelectionUtils._kHandlesPadding),
0
),
child: handle
);
case TextSelectionHandleType.collapsed:
return new Container();
}
return null;
}
}
}

71
com.unity.uiwidgets/Runtime/cupertino/thumb_painter.cs


using System.Collections.Generic;
public class CupertinoThumbPainterUtils {
public static Color _kThumbBorderColor = new Color(0x0A000000);
public static List<BoxShadow> _kSwitchBoxShadows = new List<BoxShadow> {
new BoxShadow(
color: new Color(0x26000000),
offset: new Offset(0, 3),
blurRadius: 8.0f
),
new BoxShadow(
color: new Color(0x0F000000),
offset: new Offset(0, 3),
blurRadius: 1.0f
),
};
public static List<BoxShadow> _kSliderBoxShadows = new List<BoxShadow>(){
new BoxShadow(
color: new Color(0x26000000),
offset: new Offset(0, 3),
blurRadius: 8.0f
),
new BoxShadow(
color: new Color(0x29000000),
offset: new Offset(0, 1),
blurRadius: 1.0f
),
new BoxShadow(
color: new Color(0x1A000000),
offset: new Offset(0, 3),
blurRadius: 1.0f
)
};
}
Color shadowColor = null
List<BoxShadow> shadows = null
_shadowPaint = new BoxShadow(
color: shadowColor,
blurRadius: 1.0f
).toPaint();
this.shadowColor = shadowColor ?? new Color(0x2C000000);
this.shadows = shadows ?? CupertinoThumbPainterUtils._kSliderBoxShadows;
}
public static CupertinoThumbPainter switchThumb(
Color color = null,
List<BoxShadow> shadows = null
) {
return new CupertinoThumbPainter(
color : color ?? CupertinoColors.white,
shadows : shadows ?? CupertinoThumbPainterUtils._kSwitchBoxShadows);
public readonly Color shadowColor;
public readonly List<BoxShadow> shadows;
public readonly Paint _shadowPaint;

public void paint(Canvas canvas, Rect rect) {
RRect rrect = RRect.fromRectAndRadius(

canvas.drawRRect(rrect, _shadowPaint);
canvas.drawRRect(rrect.shift(new Offset(0.0f, 3.0f)), _shadowPaint);
var _paint = new Paint();
_paint.color = color;
canvas.drawRRect(rrect, _paint);
foreach (BoxShadow shadow in shadows)
canvas.drawRRect(rrect.shift(shadow.offset), shadow.toPaint());
canvas.drawRRect(
rrect.inflate(0.5f),
new Paint(){color = CupertinoThumbPainterUtils._kThumbBorderColor}
);
canvas.drawRRect(rrect, new Paint(){color = color});
}
}
}

2
com.unity.uiwidgets/Runtime/painting/alignment.cs


this.y = y;
}
public readonly double y;
public readonly float y;
public static readonly TextAlignVertical top = new TextAlignVertical(y: -1.0f);

1
com.unity.uiwidgets/Runtime/rendering/custom_paint.cs


namespace Unity.UIWidgets.widgets {
public interface CustomPainter : Listenable {
void paint(Canvas canvas, Size size);
bool shouldRepaint(CustomPainter oldDelegate);

正在加载...
取消
保存