浏览代码
Merge branch 'dev_1.17.5' of github.com:Unity-Technologies/com.unity.uiwidgets into fix_runtime_errors
/siyaoH-1.17-PlatformMessage
Merge branch 'dev_1.17.5' of github.com:Unity-Technologies/com.unity.uiwidgets into fix_runtime_errors
/siyaoH-1.17-PlatformMessage
xingweizhu
4 年前
当前提交
64c8fb43
共有 47 个文件被更改,包括 3338 次插入 和 1463 次删除
-
4com.unity.uiwidgets/Runtime/animation/animation_controller.cs
-
23com.unity.uiwidgets/Runtime/cupertino/app.cs
-
30com.unity.uiwidgets/Runtime/foundation/assertions.cs
-
27com.unity.uiwidgets/Runtime/foundation/diagnostics.cs
-
19com.unity.uiwidgets/Runtime/painting/alignment.cs
-
39com.unity.uiwidgets/Runtime/painting/inline_span.cs
-
15com.unity.uiwidgets/Runtime/painting/placeholder_span.cs
-
125com.unity.uiwidgets/Runtime/painting/text_span.cs
-
18com.unity.uiwidgets/Runtime/rendering/animated_size.cs
-
3com.unity.uiwidgets/Runtime/rendering/layer.cs
-
60com.unity.uiwidgets/Runtime/rendering/object.cs
-
11com.unity.uiwidgets/Runtime/rendering/paragraph.cs
-
16com.unity.uiwidgets/Runtime/rendering/proxy_box.cs
-
3com.unity.uiwidgets/Runtime/rendering/sliver.cs
-
60com.unity.uiwidgets/Runtime/rendering/viewport.cs
-
1com.unity.uiwidgets/Runtime/scheduler2/binding.cs
-
14com.unity.uiwidgets/Runtime/service/raw_keyboard.cs
-
65com.unity.uiwidgets/Runtime/service/system_chrome.cs
-
2com.unity.uiwidgets/Runtime/ui2/painting.cs
-
10com.unity.uiwidgets/Runtime/widgets/actions.cs
-
19com.unity.uiwidgets/Runtime/widgets/animated_cross_fade.cs
-
20com.unity.uiwidgets/Runtime/widgets/animated_size.cs
-
11com.unity.uiwidgets/Runtime/widgets/animated_switcher.cs
-
177com.unity.uiwidgets/Runtime/widgets/app.cs
-
581com.unity.uiwidgets/Runtime/widgets/basic.cs
-
2com.unity.uiwidgets/Runtime/widgets/binding.cs
-
7com.unity.uiwidgets/Runtime/widgets/editable_text.cs
-
475com.unity.uiwidgets/Runtime/widgets/focus_manager.cs
-
144com.unity.uiwidgets/Runtime/widgets/focus_scope.cs
-
6com.unity.uiwidgets/Runtime/widgets/implicit_animations.cs
-
109com.unity.uiwidgets/Runtime/widgets/sliver.cs
-
42com.unity.uiwidgets/Runtime/widgets/text_selection.cs
-
43com.unity.uiwidgets/Runtime/widgets/ticker_provider.cs
-
109com.unity.uiwidgets/Runtime/widgets/transitions.cs
-
7com.unity.uiwidgets/Runtime/widgets/value_listenable_builder.cs
-
25com.unity.uiwidgets/Runtime/widgets/viewport.cs
-
111com.unity.uiwidgets/Runtime/widgets/visibility.cs
-
934com.unity.uiwidgets/Runtime/widgets/widget_inspector.cs
-
62com.unity.uiwidgets/Runtime/widgets/widget_span.cs
-
37com.unity.uiwidgets/Runtime/foundation/diagnosticable.mixin.gen.cs
-
40com.unity.uiwidgets/Runtime/foundation/diagnosticable.mixin.njk
-
333com.unity.uiwidgets/Runtime/rendering/proxy_sliver.cs
-
398com.unity.uiwidgets/Runtime/services/keyboard_key.cs
-
440com.unity.uiwidgets/Runtime/widgets/shortcuts.cs
-
38com.unity.uiwidgets/Runtime/widgets/title.cs
-
65com.unity.uiwidgets/Runtime/widgets/tween_animation_builder.cs
-
21com.unity.uiwidgets/Runtime/widgets/unique_widget.cs
934
com.unity.uiwidgets/Runtime/widgets/widget_inspector.cs
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
|
|||
namespace Unity.UIWidgets.foundation { |
|||
public class DiagnosticableMixinChangeNotifier : ChangeNotifier, IDiagnosticable { |
|||
protected DiagnosticableMixinChangeNotifier() { |
|||
} |
|||
|
|||
public virtual string toStringShort() { |
|||
return foundation_.describeIdentity(this); |
|||
} |
|||
|
|||
public override string ToString() { |
|||
return toString(); |
|||
} |
|||
|
|||
public virtual string toString(DiagnosticLevel minLevel = DiagnosticLevel.debug) { |
|||
string fullString = null; |
|||
D.assert(() => { |
|||
fullString = toDiagnosticsNode(style: DiagnosticsTreeStyle.singleLine) |
|||
.toString(minLevel: minLevel); |
|||
return true; |
|||
}); |
|||
return fullString ?? toStringShort(); |
|||
} |
|||
|
|||
public virtual DiagnosticsNode toDiagnosticsNode( |
|||
string name = null, |
|||
DiagnosticsTreeStyle style = DiagnosticsTreeStyle.sparse) { |
|||
return new DiagnosticableNode<DiagnosticableMixinChangeNotifier>( |
|||
name: name, value: this, style: style |
|||
); |
|||
} |
|||
|
|||
public virtual void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|
|||
namespace Unity.UIWidgets.foundation { |
|||
{% macro DiagnosticableMixin(with) %} |
|||
{% set className = 'DiagnosticableMixin' + with %} |
|||
public class {{className}} : {{with}}, IDiagnosticable { |
|||
protected {{className}}() { |
|||
} |
|||
|
|||
public virtual string toStringShort() { |
|||
return foundation_.describeIdentity(this); |
|||
} |
|||
|
|||
public override string ToString() { |
|||
return toString(); |
|||
} |
|||
|
|||
public virtual string toString(DiagnosticLevel minLevel = DiagnosticLevel.debug) { |
|||
string fullString = null; |
|||
D.assert(() => { |
|||
fullString = toDiagnosticsNode(style: DiagnosticsTreeStyle.singleLine) |
|||
.toString(minLevel: minLevel); |
|||
return true; |
|||
}); |
|||
return fullString ?? toStringShort(); |
|||
} |
|||
|
|||
public virtual DiagnosticsNode toDiagnosticsNode( |
|||
string name = null, |
|||
DiagnosticsTreeStyle style = DiagnosticsTreeStyle.sparse) { |
|||
return new DiagnosticableNode<{{className}}>( |
|||
name: name, value: this, style: style |
|||
); |
|||
} |
|||
|
|||
public virtual void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|||
} |
|||
} |
|||
{% endmacro %} |
|||
{{ DiagnosticableMixin('ChangeNotifier') }} |
|||
} |
|||
|
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Unity.UIWidgets.animation; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.gestures; |
|||
using Unity.UIWidgets.painting; |
|||
using Unity.UIWidgets.ui; |
|||
|
|||
namespace Unity.UIWidgets.rendering { |
|||
public abstract class RenderProxySliver : RenderSliver , RenderObjectWithChildMixin<RenderSliver> { |
|||
public RenderProxySliver(RenderSliver child = null) { |
|||
this.child = child; |
|||
} |
|||
|
|||
RenderSliver _child; |
|||
public RenderSliver child { |
|||
get { return _child; } |
|||
set { |
|||
if (_child != null) |
|||
dropChild(_child); |
|||
_child = value; |
|||
if (_child != null) |
|||
adoptChild(_child); |
|||
} |
|||
} |
|||
public override void setupParentData(RenderObject child) { |
|||
if (!(child.parentData is SliverPhysicalParentData)) |
|||
child.parentData = new SliverPhysicalParentData(); |
|||
} |
|||
|
|||
protected override void performLayout() { |
|||
D.assert(child != null); |
|||
child.layout(constraints, parentUsesSize: true); |
|||
geometry = child.geometry; |
|||
} |
|||
public override void paint(PaintingContext context, Offset offset) { |
|||
if (child != null) |
|||
context.paintChild(child, offset); |
|||
} |
|||
|
|||
protected override bool hitTestChildren(SliverHitTestResult result, float mainAxisPosition = 0, float crossAxisPosition = 0) { |
|||
return child != null |
|||
&& child.geometry.hitTestExtent > 0 |
|||
&& child.hitTest( |
|||
result, |
|||
mainAxisPosition: mainAxisPosition, |
|||
crossAxisPosition: crossAxisPosition); |
|||
} |
|||
public override float childMainAxisPosition(RenderObject child) { |
|||
child = (RenderSliver)child; |
|||
D.assert(child != null); |
|||
D.assert(child == this.child); |
|||
return 0.0f; |
|||
} |
|||
public override void applyPaintTransform(RenderObject child, Matrix4 transform) { |
|||
D.assert(child != null); |
|||
SliverPhysicalParentData childParentData = child.parentData as SliverPhysicalParentData; |
|||
childParentData.applyPaintTransform(transform); |
|||
} |
|||
|
|||
public bool debugValidateChild(RenderObject child) { |
|||
D.assert(() => { |
|||
if (!(child is RenderSliver)) { |
|||
string result = ""; |
|||
result += new ErrorDescription( |
|||
$"A {GetType()} expected a child of type $ChildType but received a " + |
|||
$"child of type {child.GetType()}."); |
|||
result += new ErrorDescription( |
|||
"RenderObjects expect specific types of children because they " + |
|||
"coordinate with their children during layout and paint. For " + |
|||
"example, a RenderSliver cannot be the child of a RenderBox because " + |
|||
"a RenderSliver does not understand the RenderBox layout protocol." |
|||
); |
|||
result += new ErrorSpacer(); |
|||
result += new DiagnosticsProperty<dynamic>( |
|||
$"The {GetType()} that expected a $ChildType child was created by", |
|||
debugCreator, |
|||
style: DiagnosticsTreeStyle.errorProperty |
|||
); |
|||
result += new ErrorSpacer(); |
|||
result += new DiagnosticsProperty<dynamic>( |
|||
$"The {child.GetType()} that did not match the expected child type " + |
|||
"was created by", |
|||
child.debugCreator, |
|||
style: DiagnosticsTreeStyle.errorProperty |
|||
); |
|||
throw new UIWidgetsError(result); |
|||
} |
|||
|
|||
return true; |
|||
}); |
|||
return true; |
|||
|
|||
} |
|||
|
|||
RenderObject RenderObjectWithChildMixin.child { |
|||
get { return child; } |
|||
set { child = (RenderSliver) value; } |
|||
} |
|||
} |
|||
public class RenderSliverOpacity : RenderProxySliver { |
|||
public RenderSliverOpacity( |
|||
RenderSliver sliver = null, |
|||
float opacity = 1.0f, |
|||
bool alwaysIncludeSemantics = false |
|||
) : base( child:sliver) { |
|||
D.assert(opacity != null && opacity >= 0.0 && opacity <= 1.0); |
|||
D.assert(alwaysIncludeSemantics != null); |
|||
_opacity = opacity; |
|||
_alwaysIncludeSemantics = alwaysIncludeSemantics; |
|||
_alpha = ui.Color.getAlphaFromOpacity(opacity); |
|||
child = sliver; |
|||
} |
|||
|
|||
|
|||
bool alwaysNeedsCompositing { |
|||
get { return child != null && (_alpha != 0 && _alpha != 255);} |
|||
} |
|||
int _alpha; |
|||
|
|||
public float opacity { |
|||
get { return _opacity; } |
|||
set { |
|||
D.assert(value != null); |
|||
D.assert(value >= 0.0 && value <= 1.0); |
|||
if (_opacity == value) |
|||
return; |
|||
bool didNeedCompositing = alwaysNeedsCompositing; |
|||
bool wasVisible = _alpha != 0; |
|||
_opacity = value; |
|||
_alpha = ui.Color.getAlphaFromOpacity(_opacity); |
|||
if (didNeedCompositing != alwaysNeedsCompositing) |
|||
markNeedsCompositingBitsUpdate(); |
|||
markNeedsPaint(); |
|||
//if (wasVisible != (_alpha != 0) && !alwaysIncludeSemantics)
|
|||
// markNeedsSemanticsUpdate();
|
|||
} |
|||
} |
|||
float _opacity; |
|||
|
|||
public bool alwaysIncludeSemantics { |
|||
get { return _alwaysIncludeSemantics;} |
|||
set { |
|||
if (value == _alwaysIncludeSemantics) |
|||
return; |
|||
_alwaysIncludeSemantics = value; |
|||
// markNeedsSemanticsUpdate();
|
|||
} |
|||
} |
|||
bool _alwaysIncludeSemantics; |
|||
public override void paint(PaintingContext context, Offset offset) { |
|||
if (child != null && child.geometry.visible) { |
|||
if (_alpha == 0) { |
|||
setLayer(null); |
|||
return; |
|||
} |
|||
if (_alpha == 255) { |
|||
setLayer(null); |
|||
context.paintChild(child, offset); |
|||
return; |
|||
} |
|||
D.assert(needsCompositing); |
|||
var opacity = context.pushOpacity( |
|||
offset, |
|||
_alpha, |
|||
base.paint, |
|||
oldLayer: layer as OpacityLayer |
|||
); |
|||
setLayer(opacity); |
|||
} |
|||
} |
|||
/*public override void visitChildrenForSemantics(RenderObject visitor) { |
|||
visitor = (RenderObjectVisitor)visitor; |
|||
if (child != null && (_alpha != 0 || alwaysIncludeSemantics)) |
|||
visitor(child); |
|||
}*/ |
|||
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|||
base.debugFillProperties(properties); |
|||
properties.add(new FloatProperty("opacity", opacity)); |
|||
properties.add(new FlagProperty("alwaysIncludeSemantics", value: alwaysIncludeSemantics, ifTrue: "alwaysIncludeSemantics")); |
|||
} |
|||
} |
|||
|
|||
public class RenderSliverIgnorePointer : RenderProxySliver { |
|||
public RenderSliverIgnorePointer( |
|||
RenderSliver sliver = null, |
|||
bool ignoring = true, |
|||
bool? ignoringSemantics = null |
|||
):base(child:sliver){ |
|||
child = sliver; |
|||
D.assert(ignoring != null); |
|||
_ignoring = ignoring; |
|||
_ignoringSemantics = ignoringSemantics; |
|||
} |
|||
|
|||
|
|||
public bool ignoring { |
|||
get { return _ignoring; } |
|||
set { |
|||
D.assert(value != null); |
|||
if (value == _ignoring) |
|||
return; |
|||
_ignoring = value; |
|||
//if (_ignoringSemantics == null || !_ignoringSemantics)
|
|||
// markNeedsSemanticsUpdate();
|
|||
} |
|||
} |
|||
bool _ignoring; |
|||
|
|||
|
|||
public bool? ignoringSemantics { |
|||
get { return _ignoringSemantics; } |
|||
set { |
|||
if (value == _ignoringSemantics) |
|||
return ; |
|||
bool oldEffectiveValue = _effectiveIgnoringSemantics; |
|||
_ignoringSemantics = value; |
|||
//if (oldEffectiveValue != _effectiveIgnoringSemantics)
|
|||
// markNeedsSemanticsUpdate();
|
|||
|
|||
} |
|||
} |
|||
bool? _ignoringSemantics; |
|||
|
|||
|
|||
bool _effectiveIgnoringSemantics { |
|||
get { return ignoringSemantics ?? ignoring; } |
|||
} |
|||
|
|||
public override bool hitTest(SliverHitTestResult result, float mainAxisPosition = 0, float crossAxisPosition = 0) { |
|||
return !ignoring && base.hitTest( |
|||
result, |
|||
mainAxisPosition: mainAxisPosition, |
|||
crossAxisPosition: crossAxisPosition |
|||
); |
|||
} |
|||
/*public override void visitChildrenForSemantics(RenderObjectVisitor visitor) { |
|||
if (child != null && !_effectiveIgnoringSemantics) |
|||
visitor(child); |
|||
}*/ |
|||
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|||
base.debugFillProperties(properties); |
|||
properties.add(new DiagnosticsProperty<bool>("ignoring", ignoring)); |
|||
properties.add(new DiagnosticsProperty<bool>("ignoringSemantics", _effectiveIgnoringSemantics, description: ignoringSemantics == null ? $"implicitly {_effectiveIgnoringSemantics}" : null)); |
|||
} |
|||
} |
|||
public class RenderSliverOffstage : RenderProxySliver { |
|||
public RenderSliverOffstage( |
|||
RenderSliver sliver = null, |
|||
bool offstage = true): base(child:sliver) { |
|||
D.assert(offstage != null); |
|||
_offstage = offstage; |
|||
child = sliver; |
|||
} |
|||
|
|||
public bool offstage { |
|||
get { return _offstage; } |
|||
set { |
|||
D.assert(value != null); |
|||
if (value == _offstage) |
|||
return; |
|||
_offstage = value; |
|||
markNeedsLayoutForSizedByParentChange(); |
|||
} |
|||
} |
|||
bool _offstage; |
|||
|
|||
protected override void performLayout() { |
|||
D.assert(child != null); |
|||
child.layout(constraints, parentUsesSize: true); |
|||
if (!offstage) |
|||
geometry = child.geometry; |
|||
else |
|||
geometry = new SliverGeometry( |
|||
scrollExtent: 0.0f, |
|||
visible: false, |
|||
maxPaintExtent: 0.0f); |
|||
} |
|||
public override bool hitTest(SliverHitTestResult result, float mainAxisPosition = 0, float crossAxisPosition = 0) { |
|||
return !offstage && base.hitTest(result, mainAxisPosition: mainAxisPosition, crossAxisPosition: crossAxisPosition); |
|||
} |
|||
protected override bool hitTestChildren(SliverHitTestResult result, float mainAxisPosition = 0, float crossAxisPosition = 0) { |
|||
return !offstage |
|||
&& child != null |
|||
&& child.geometry.hitTestExtent > 0 |
|||
&& child.hitTest( |
|||
result, |
|||
mainAxisPosition: mainAxisPosition, |
|||
crossAxisPosition: crossAxisPosition |
|||
); |
|||
} |
|||
public override void paint(PaintingContext context, Offset offset) { |
|||
if (offstage) |
|||
return; |
|||
context.paintChild(child, offset); |
|||
} |
|||
|
|||
/*public override void visitChildrenForSemantics(RenderObjectVisitor visitor) { |
|||
if (offstage) |
|||
return; |
|||
base.visitChildrenForSemantics(visitor); |
|||
}*/ |
|||
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|||
base.debugFillProperties(properties); |
|||
properties.add(new DiagnosticsProperty<bool>("offstage", offstage)); |
|||
} |
|||
public override List<DiagnosticsNode> debugDescribeChildren() { |
|||
if (child == null) |
|||
return new List<DiagnosticsNode>(); |
|||
return new List<DiagnosticsNode>{ |
|||
child.toDiagnosticsNode( |
|||
name: "child", |
|||
style: offstage ? DiagnosticsTreeStyle.offstage : DiagnosticsTreeStyle.sparse |
|||
), |
|||
}; |
|||
} |
|||
} |
|||
/*public class RenderSliverAnimatedOpacity : RenderProxySliver ,RenderAnimatedOpacityMixin<RenderSliver>{ |
|||
public RenderSliverAnimatedOpacity( |
|||
Animation<double> opacity = null, |
|||
bool alwaysIncludeSemantics = false, |
|||
RenderSliver sliver = null |
|||
):base(sliver) { |
|||
D.assert(opacity != null); |
|||
D.assert(alwaysIncludeSemantics != null); |
|||
this.opacity = opacity; |
|||
this.alwaysIncludeSemantics = alwaysIncludeSemantics; |
|||
child = sliver; |
|||
} |
|||
}*/ |
|||
|
|||
|
|||
} |
|
|||
|
|||
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using Unity.UIWidgets.foundation; |
|||
|
|||
namespace Unity.UIWidgets.services |
|||
{ |
|||
public abstract class KeyboardKey : Diagnosticable |
|||
{ |
|||
protected KeyboardKey() { } |
|||
} |
|||
|
|||
public class LogicalKeyboardKey : KeyboardKey, IEquatable<LogicalKeyboardKey> |
|||
{ |
|||
public bool Equals(LogicalKeyboardKey other) |
|||
{ |
|||
if (ReferenceEquals(null, other)) { |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, other)) { |
|||
return true; |
|||
} |
|||
|
|||
return keyId == other.keyId; |
|||
} |
|||
|
|||
public override bool Equals(object obj) |
|||
{ |
|||
if (ReferenceEquals(null, obj)) { |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, obj)) { |
|||
return true; |
|||
} |
|||
|
|||
if (obj.GetType() != GetType()) { |
|||
return false; |
|||
} |
|||
|
|||
return Equals((LogicalKeyboardKey) obj); |
|||
} |
|||
|
|||
public override int GetHashCode() |
|||
{ |
|||
unchecked |
|||
{ |
|||
int hashCode = (int)keyId; |
|||
hashCode = (hashCode * 397) ^ (debugName != null ? debugName.GetHashCode() : 0); |
|||
hashCode = (hashCode * 397) ^ (keyLabel != null ? keyLabel.GetHashCode() : 0); |
|||
return hashCode; |
|||
} |
|||
} |
|||
|
|||
protected LogicalKeyboardKey(long keyId, string debugName = null, string keyLabel = null) : base() |
|||
{ |
|||
D.assert(keyId != null); |
|||
this.keyId = keyId; |
|||
this.debugName = debugName; |
|||
this.keyLabel = keyLabel; |
|||
} |
|||
|
|||
public readonly long keyId; |
|||
|
|||
public readonly string debugName; |
|||
|
|||
public readonly string keyLabel; |
|||
|
|||
public static LogicalKeyboardKey findKeyByKeyId(int keyId) => _knownLogicalKeys[keyId]; |
|||
|
|||
public static bool isControlCharacter(string label) |
|||
{ |
|||
if (label.Length > 1) |
|||
{ |
|||
return false; |
|||
} |
|||
int codeUnit = label[0]; |
|||
return (codeUnit <= 0x1f && codeUnit >= 0x00) || (codeUnit >= 0x7f && codeUnit <= 0x9f); |
|||
} |
|||
|
|||
public bool isAutogenerated |
|||
{ |
|||
get |
|||
{ |
|||
return (keyId & autogeneratedMask) != 0; |
|||
} |
|||
} |
|||
|
|||
public HashSet<LogicalKeyboardKey> synonyms |
|||
{ |
|||
get { |
|||
HashSet<LogicalKeyboardKey> result = new HashSet<LogicalKeyboardKey>(); |
|||
LogicalKeyboardKey item = _synonyms[this]; |
|||
if (item == null) { |
|||
return result; |
|||
} |
|||
result.Add(item: item); |
|||
return result; |
|||
} |
|||
} |
|||
|
|||
public static HashSet<LogicalKeyboardKey> collapseSynonyms(HashSet<LogicalKeyboardKey> input) |
|||
{ |
|||
HashSet<LogicalKeyboardKey> result = new HashSet<LogicalKeyboardKey>(); |
|||
foreach (LogicalKeyboardKey key in input) |
|||
{ |
|||
LogicalKeyboardKey synonym = _synonyms[key]; |
|||
result.Add(synonym ?? key); |
|||
} |
|||
return result; |
|||
} |
|||
|
|||
|
|||
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|||
base.debugFillProperties(properties); |
|||
properties.add(new StringProperty("keyId", keyId.ToString().PadLeft(8,'\0'), showName: true)); |
|||
properties.add(new StringProperty("keyLabel", keyLabel, showName: true)); |
|||
properties.add(new StringProperty("debugName", debugName, showName: true, defaultValue: null)); |
|||
} |
|||
|
|||
/// Mask for the 32-bit value portion of the key code.
|
|||
///
|
|||
/// This is used by platform-specific code to generate Flutter key codes.
|
|||
public static readonly long valueMask = 0x000FFFFFFFF; |
|||
|
|||
/// Mask for the platform prefix portion of the key code.
|
|||
///
|
|||
/// This is used by platform-specific code to generate Flutter key codes.
|
|||
public static readonly long platformMask = 0x0FF00000000; |
|||
|
|||
/// Mask for the auto-generated bit portion of the key code.
|
|||
///
|
|||
/// This is used by platform-specific code to generate new Flutter key codes
|
|||
/// for keys which are not recognized.
|
|||
public static readonly long autogeneratedMask = 0x10000000000; |
|||
|
|||
/// Mask for the synonym pseudo-keys generated for keys which appear in more
|
|||
/// than one place on the keyboard.
|
|||
///
|
|||
/// IDs in this range are used to represent keys which appear in multiple
|
|||
/// places on the keyboard, such as the SHIFT, ALT, CTRL, and numeric keypad
|
|||
/// keys. These key codes will never be generated by the key event system, but
|
|||
/// may be used in key maps to represent the union of all the keys of each
|
|||
/// type in order to match them.
|
|||
///
|
|||
/// To look up the synonyms that are defined, look in the [synonyms] map.
|
|||
public static readonly long synonymMask = 0x20000000000; |
|||
|
|||
/// The code prefix for keys which have a Unicode representation.
|
|||
///
|
|||
/// This is used by platform-specific code to generate Flutter key codes.
|
|||
public static readonly long unicodePlane = 0x00000000000; |
|||
|
|||
/// The code prefix for keys which do not have a Unicode representation.
|
|||
///
|
|||
/// This is used by platform-specific code to generate Flutter key codes using
|
|||
/// HID Usage codes.
|
|||
public static readonly long hidPlane = 0x00100000000; |
|||
|
|||
/// Represents the logical "None" key on the keyboard.
|
|||
///
|
|||
/// See the function [RawKeyEvent.logicalKey] for more information.
|
|||
public static readonly LogicalKeyboardKey none = new LogicalKeyboardKey(0x00100000000, debugName: foundation_.kReleaseMode ? null : "None"); |
|||
|
|||
/// Represents the logical "Control Left" key on the keyboard.
|
|||
///
|
|||
/// See the function [RawKeyEvent.logicalKey] for more information.
|
|||
public static readonly LogicalKeyboardKey controlLeft = new LogicalKeyboardKey(0x001000700e0, debugName: foundation_.kReleaseMode ? null : "Control Left"); |
|||
|
|||
/// Represents the logical "Shift Left" key on the keyboard.
|
|||
///
|
|||
/// See the function [RawKeyEvent.logicalKey] for more information.
|
|||
public static readonly LogicalKeyboardKey shiftLeft = new LogicalKeyboardKey(0x001000700e1, debugName: foundation_.kReleaseMode ? null : "Shift Left"); |
|||
|
|||
/// Represents the logical "Alt Left" key on the keyboard.
|
|||
///
|
|||
/// See the function [RawKeyEvent.logicalKey] for more information.
|
|||
public static readonly LogicalKeyboardKey altLeft = new LogicalKeyboardKey(0x001000700e2, debugName: foundation_.kReleaseMode ? null : "Alt Left"); |
|||
|
|||
/// Represents the logical "Meta Left" key on the keyboard.
|
|||
///
|
|||
/// See the function [RawKeyEvent.logicalKey] for more information.
|
|||
public static readonly LogicalKeyboardKey metaLeft = new LogicalKeyboardKey(0x001000700e3, debugName: foundation_.kReleaseMode ? null : "Meta Left"); |
|||
|
|||
/// Represents the logical "Control Right" key on the keyboard.
|
|||
///
|
|||
/// See the function [RawKeyEvent.logicalKey] for more information.
|
|||
public static readonly LogicalKeyboardKey controlRight = new LogicalKeyboardKey(0x001000700e4, debugName: foundation_.kReleaseMode ? null : "Control Right"); |
|||
|
|||
/// Represents the logical "Shift Right" key on the keyboard.
|
|||
///
|
|||
/// See the function [RawKeyEvent.logicalKey] for more information.
|
|||
public static readonly LogicalKeyboardKey shiftRight = new LogicalKeyboardKey(0x001000700e5, debugName: foundation_.kReleaseMode ? null : "Shift Right"); |
|||
|
|||
/// Represents the logical "Alt Right" key on the keyboard.
|
|||
///
|
|||
/// See the function [RawKeyEvent.logicalKey] for more information.
|
|||
public static readonly LogicalKeyboardKey altRight = new LogicalKeyboardKey(0x001000700e6, debugName: foundation_.kReleaseMode ? null : "Alt Right"); |
|||
|
|||
/// Represents the logical "Meta Right" key on the keyboard.
|
|||
///
|
|||
/// See the function [RawKeyEvent.logicalKey] for more information.
|
|||
public static readonly LogicalKeyboardKey metaRight = new LogicalKeyboardKey(0x001000700e7, debugName: foundation_.kReleaseMode ? null : "Meta Right"); |
|||
|
|||
/// Represents the logical "Shift" key on the keyboard.
|
|||
///
|
|||
/// This key represents the union of the keys {shiftLeft, shiftRight} when
|
|||
/// comparing keys. This key will never be generated directly, its main use is
|
|||
/// in defining key maps.
|
|||
public static readonly LogicalKeyboardKey shift = new LogicalKeyboardKey(0x201000700e1, debugName: foundation_.kReleaseMode ? null : "Shift"); |
|||
|
|||
/// Represents the logical "Meta" key on the keyboard.
|
|||
///
|
|||
/// This key represents the union of the keys {metaLeft, metaRight} when
|
|||
/// comparing keys. This key will never be generated directly, its main use is
|
|||
/// in defining key maps.
|
|||
public static readonly LogicalKeyboardKey meta = new LogicalKeyboardKey(0x201000700e3, debugName: foundation_.kReleaseMode ? null : "Meta"); |
|||
|
|||
/// Represents the logical "Alt" key on the keyboard.
|
|||
///
|
|||
/// This key represents the union of the keys {altLeft, altRight} when
|
|||
/// comparing keys. This key will never be generated directly, its main use is
|
|||
/// in defining key maps.
|
|||
public static readonly LogicalKeyboardKey alt = new LogicalKeyboardKey(0x201000700e2, debugName: foundation_.kReleaseMode ? null : "Alt"); |
|||
|
|||
/// Represents the logical "Control" key on the keyboard.
|
|||
///
|
|||
/// This key represents the union of the keys {controlLeft, controlRight} when
|
|||
/// comparing keys. This key will never be generated directly, its main use is
|
|||
/// in defining key maps.
|
|||
public static readonly LogicalKeyboardKey control = new LogicalKeyboardKey(0x201000700e0, debugName: foundation_.kReleaseMode ? null : "Control"); |
|||
|
|||
// A list of all predefined constant LogicalKeyboardKeys so they can be
|
|||
// searched.
|
|||
public static readonly Dictionary<long, LogicalKeyboardKey> _knownLogicalKeys = new Dictionary<long, LogicalKeyboardKey>{ |
|||
{0x0100000000, none}, |
|||
{0x201000700e1, shift}, |
|||
{0x201000700e3, meta}, |
|||
{0x201000700e2, alt}, |
|||
{0x201000700e0, control}, |
|||
}; |
|||
|
|||
// A map of keys to the pseudo-key synonym for that key. Used by getSynonyms.
|
|||
public static readonly Dictionary<LogicalKeyboardKey, LogicalKeyboardKey> _synonyms = new Dictionary<LogicalKeyboardKey, LogicalKeyboardKey>{ |
|||
{shiftLeft, shift}, |
|||
{shiftRight, shift}, |
|||
{metaLeft, meta}, |
|||
{metaRight, meta}, |
|||
{altLeft, alt}, |
|||
{altRight, alt}, |
|||
{controlLeft, control}, |
|||
{controlRight, control}, |
|||
}; |
|||
} |
|||
|
|||
public class PhysicalKeyboardKey : KeyboardKey, IEquatable<PhysicalKeyboardKey> |
|||
{ |
|||
|
|||
protected PhysicalKeyboardKey(int usbHidUsage, string debugName = null) |
|||
{ |
|||
D.assert(usbHidUsage != null); |
|||
this.usbHidUsage = usbHidUsage; |
|||
this.debugName = debugName; |
|||
} |
|||
|
|||
|
|||
/// The unique USB HID usage ID of this physical key on the keyboard.
|
|||
///
|
|||
/// Due to the variations in platform APIs, this may not be the actual HID
|
|||
/// usage code from the hardware, but a value derived from available
|
|||
/// information on the platform.
|
|||
///
|
|||
/// See <https://www.usb.org/sites/default/files/documents/hut1_12v2.pdf>
|
|||
/// for the HID usage values and their meanings.
|
|||
public readonly int usbHidUsage; |
|||
|
|||
/// The debug string to print for this keyboard key, which will be null in
|
|||
/// release mode.
|
|||
public readonly string debugName; |
|||
|
|||
/// Finds a known [PhysicalKeyboardKey] that matches the given USB HID usage
|
|||
/// code.
|
|||
public static PhysicalKeyboardKey findKeyByCode(int usageCode) => _knownPhysicalKeys[usageCode]; |
|||
|
|||
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|||
base.debugFillProperties(properties); |
|||
properties.add(new StringProperty("usbHidUsage", usbHidUsage.ToString().PadLeft(8,'0'), showName: true)); |
|||
properties.add(new StringProperty("debugName", debugName, showName: true, defaultValue: null)); |
|||
} |
|||
|
|||
public bool Equals(PhysicalKeyboardKey other) |
|||
{ |
|||
if (ReferenceEquals(null, other)) { |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, other)) { |
|||
return true; |
|||
} |
|||
|
|||
return usbHidUsage == other.usbHidUsage; |
|||
} |
|||
|
|||
public override bool Equals(object obj) |
|||
{ |
|||
if (ReferenceEquals(null, obj)) { |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, obj)) { |
|||
return true; |
|||
} |
|||
|
|||
if (obj.GetType() != GetType()) { |
|||
return false; |
|||
} |
|||
|
|||
return Equals((PhysicalKeyboardKey) obj); |
|||
} |
|||
|
|||
public override int GetHashCode() |
|||
{ |
|||
unchecked |
|||
{ |
|||
return (usbHidUsage * 397) ^ (debugName != null ? debugName.GetHashCode() : 0); |
|||
} |
|||
} |
|||
// Key constants for all keyboard keys in the USB HID specification at the
|
|||
// time Flutter was built.
|
|||
|
|||
/// Represents the location of the "None" key on a generalized keyboard.
|
|||
///
|
|||
/// See the function [RawKeyEvent.physicalKey] for more information.
|
|||
public static readonly PhysicalKeyboardKey none = new PhysicalKeyboardKey(0x00000000, debugName: foundation_.kReleaseMode ? null : "None"); |
|||
|
|||
/// Represents the location of the "Control Left" key on a generalized
|
|||
/// keyboard.
|
|||
///
|
|||
/// See the function [RawKeyEvent.physicalKey] for more information.
|
|||
public static readonly PhysicalKeyboardKey controlLeft = new PhysicalKeyboardKey(0x000700e0, debugName: foundation_.kReleaseMode ? null : "Control Left"); |
|||
|
|||
/// Represents the location of the "Shift Left" key on a generalized keyboard.
|
|||
///
|
|||
/// See the function [RawKeyEvent.physicalKey] for more information.
|
|||
public static readonly PhysicalKeyboardKey shiftLeft = new PhysicalKeyboardKey(0x000700e1, debugName: foundation_.kReleaseMode ? null : "Shift Left"); |
|||
|
|||
/// Represents the location of the "Alt Left" key on a generalized keyboard.
|
|||
///
|
|||
/// See the function [RawKeyEvent.physicalKey] for more information.
|
|||
public static readonly PhysicalKeyboardKey altLeft = new PhysicalKeyboardKey(0x000700e2, debugName: foundation_.kReleaseMode ? null : "Alt Left"); |
|||
|
|||
/// Represents the location of the "Meta Left" key on a generalized keyboard.
|
|||
///
|
|||
/// See the function [RawKeyEvent.physicalKey] for more information.
|
|||
public static readonly PhysicalKeyboardKey metaLeft = new PhysicalKeyboardKey(0x000700e3, debugName: foundation_.kReleaseMode ? null : "Meta Left"); |
|||
|
|||
/// Represents the location of the "Control Right" key on a generalized
|
|||
/// keyboard.
|
|||
///
|
|||
/// See the function [RawKeyEvent.physicalKey] for more information.
|
|||
public static readonly PhysicalKeyboardKey controlRight = new PhysicalKeyboardKey(0x000700e4, debugName: foundation_.kReleaseMode ? null : "Control Right"); |
|||
|
|||
/// Represents the location of the "Shift Right" key on a generalized
|
|||
/// keyboard.
|
|||
///
|
|||
/// See the function [RawKeyEvent.physicalKey] for more information.
|
|||
public static readonly PhysicalKeyboardKey shiftRight = new PhysicalKeyboardKey(0x000700e5, debugName: foundation_.kReleaseMode ? null : "Shift Right"); |
|||
|
|||
/// Represents the location of the "Alt Right" key on a generalized keyboard.
|
|||
///
|
|||
/// See the function [RawKeyEvent.physicalKey] for more information.
|
|||
public static readonly PhysicalKeyboardKey altRight = new PhysicalKeyboardKey(0x000700e6, debugName: foundation_.kReleaseMode ? null : "Alt Right"); |
|||
|
|||
/// Represents the location of the "Meta Right" key on a generalized keyboard.
|
|||
///
|
|||
/// See the function [RawKeyEvent.physicalKey] for more information.
|
|||
public static readonly PhysicalKeyboardKey metaRight = new PhysicalKeyboardKey(0x000700e7, debugName: foundation_.kReleaseMode ? null : "Meta Right"); |
|||
|
|||
|
|||
public static readonly Dictionary<int, PhysicalKeyboardKey> _knownPhysicalKeys = |
|||
new Dictionary<int, PhysicalKeyboardKey>() { |
|||
{0x00000000, none}, |
|||
{0x000700e0, controlLeft}, |
|||
{0x000700e1, shiftLeft}, |
|||
{0x000700e2, altLeft}, |
|||
{0x000700e3, metaLeft}, |
|||
{0x000700e4, controlRight}, |
|||
{0x000700e5, shiftRight}, |
|||
{0x000700e6, altRight}, |
|||
{0x000700e7, metaRight}, |
|||
}; |
|||
} |
|||
|
|||
|
|||
} |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.Linq; |
|||
using System.Runtime.CompilerServices; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.service; |
|||
using Unity.UIWidgets.services; |
|||
|
|||
namespace Unity.UIWidgets.widgets { |
|||
|
|||
public class KeySet<T> : KeyboardKey, IEquatable<KeySet<T>> |
|||
{ |
|||
public KeySet( |
|||
T key1, |
|||
T key2 = default(T), |
|||
T key3 = default(T), |
|||
T key4 = default(T) |
|||
) { |
|||
D.assert(key1 != null); |
|||
_keys = new HashSet<T>(); |
|||
_keys.Add(key1); |
|||
int count = 1; |
|||
if (key2 != null) { |
|||
_keys.Add(key2); |
|||
D.assert(() => { |
|||
count++; |
|||
return true; |
|||
}); |
|||
} |
|||
|
|||
if (key3 != null) { |
|||
_keys.Add(key3); |
|||
D.assert(() => { |
|||
count++; |
|||
return true; |
|||
}); |
|||
} |
|||
|
|||
if (key4 != null) { |
|||
_keys.Add(key4); |
|||
D.assert(() => { |
|||
count++; |
|||
return true; |
|||
}); |
|||
} |
|||
|
|||
D.assert(_keys.Count == count, |
|||
() => "Two or more provided keys are identical. Each key must appear only once."); |
|||
} |
|||
|
|||
public KeySet(HashSet<T> keys) |
|||
{ |
|||
D.assert(keys != null); |
|||
D.assert(keys.isNotEmpty); |
|||
D.assert(!keys.Contains(default(T))); |
|||
foreach (var key in keys) { |
|||
_keys.Add(key); |
|||
} |
|||
} |
|||
|
|||
public HashSet<T> keys |
|||
{ |
|||
get { return new HashSet<T>(_keys); } |
|||
} |
|||
|
|||
public readonly HashSet<T> _keys; |
|||
|
|||
|
|||
public static readonly List<int> _tempHashStore3 = new List<int>() {0, 0, 0}; // used to sort exactly 3 keys
|
|||
public static readonly List<int> _tempHashStore4 = new List<int>() {0, 0, 0, 0}; // used to sort exactly 4 keys
|
|||
|
|||
public int _hashCode; |
|||
|
|||
public bool Equals(KeySet<T> other) |
|||
{ |
|||
if (ReferenceEquals(null, other)) { |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, other)) { |
|||
return true; |
|||
} |
|||
|
|||
return Equals(_keys, other._keys) && _hashCode == other._hashCode; |
|||
} |
|||
|
|||
public override bool Equals(object obj) |
|||
{ |
|||
if (ReferenceEquals(null, obj)) { |
|||
return false; |
|||
} |
|||
|
|||
if (ReferenceEquals(this, obj)) { |
|||
return true; |
|||
} |
|||
|
|||
if (obj.GetType() != GetType()) { |
|||
return false; |
|||
} |
|||
|
|||
return Equals((KeySet<T>) obj); |
|||
} |
|||
|
|||
public override int GetHashCode() |
|||
{ |
|||
unchecked |
|||
{ |
|||
if (_hashCode != 0) { |
|||
return _hashCode; |
|||
} |
|||
|
|||
int length = _keys.Count; |
|||
IEnumerator<T> iterator = _keys.GetEnumerator(); |
|||
|
|||
// There's always at least one key. Just extract it.
|
|||
iterator.MoveNext(); |
|||
int h1 = iterator.GetHashCode(); |
|||
|
|||
if (length == 1) { |
|||
// Don't do anything fancy if there's exactly one key.
|
|||
return _hashCode = h1; |
|||
} |
|||
|
|||
iterator.MoveNext(); |
|||
int h2 = iterator.GetHashCode(); |
|||
if (length == 2) { |
|||
// No need to sort if there's two keys, just compare them.
|
|||
return _hashCode = h1 < h2 |
|||
? ((h1 != null ? h1.GetHashCode() : 0) * 397) ^ h2.GetHashCode() |
|||
: ((h2 != null ? h2.GetHashCode() : 0) * 397) ^ h1.GetHashCode(); |
|||
} |
|||
|
|||
// Sort key hash codes and feed to hashList to ensure the aggregate
|
|||
// hash code does not depend on the key order.
|
|||
List<int> sortedHashes = length == 3 |
|||
? _tempHashStore3 |
|||
: _tempHashStore4; |
|||
sortedHashes[0] = h1; |
|||
sortedHashes[1] = h2; |
|||
iterator.MoveNext(); |
|||
sortedHashes[2] = iterator.GetHashCode(); |
|||
if (length == 4) { |
|||
iterator.MoveNext(); |
|||
sortedHashes[3] = iterator.GetHashCode(); |
|||
} |
|||
sortedHashes.Sort(); |
|||
return _hashCode = (_hashCode * 397) ^ (sortedHashes != null ? sortedHashes.GetHashCode() : 0);; |
|||
} |
|||
} |
|||
} |
|||
|
|||
public class LogicalKeySet : KeySet<LogicalKeyboardKey> { |
|||
|
|||
public LogicalKeySet( |
|||
LogicalKeyboardKey key1, |
|||
LogicalKeyboardKey key2 = default(LogicalKeyboardKey), |
|||
LogicalKeyboardKey key3 = default(LogicalKeyboardKey), |
|||
LogicalKeyboardKey key4 = default(LogicalKeyboardKey) |
|||
) : base(key1: key1, key2: key2, key3: key3, key4: key4){ } |
|||
|
|||
public LogicalKeySet(HashSet<LogicalKeyboardKey> keys) : base(keys) { } |
|||
|
|||
public static readonly HashSet<LogicalKeyboardKey> _modifiers = new HashSet<LogicalKeyboardKey>(){ |
|||
LogicalKeyboardKey.alt, |
|||
LogicalKeyboardKey.control, |
|||
LogicalKeyboardKey.meta, |
|||
LogicalKeyboardKey.shift, |
|||
}; |
|||
|
|||
/// Returns a description of the key set that is short and readable.
|
|||
///
|
|||
/// Intended to be used in debug mode for logging purposes.
|
|||
public string debugDescribeKeys() { |
|||
List<LogicalKeyboardKey> sortedKeys = keys.ToList(); |
|||
sortedKeys.Sort( |
|||
(LogicalKeyboardKey a, LogicalKeyboardKey b) => { |
|||
bool aIsModifier = a.synonyms.isNotEmpty() || _modifiers.Contains(a); |
|||
bool bIsModifier = b.synonyms.isNotEmpty() || _modifiers.Contains(b); |
|||
if (aIsModifier && !bIsModifier) { |
|||
return -1; |
|||
} else if (bIsModifier && !aIsModifier) { |
|||
return 1; |
|||
} |
|||
return a.debugName.CompareTo(b.debugName); |
|||
} |
|||
); |
|||
List<string> result = new List<string>(); |
|||
foreach (var key in sortedKeys) { |
|||
result.Add(key.debugName); |
|||
} |
|||
return string.Join(" + ", result.ToArray()); |
|||
} |
|||
|
|||
|
|||
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|||
base.debugFillProperties(properties); |
|||
properties.add(new DiagnosticsProperty<HashSet<LogicalKeyboardKey>>("keys", _keys, description: debugDescribeKeys())); |
|||
} |
|||
} |
|||
|
|||
public class ShortcutMapProperty : DiagnosticsProperty<Dictionary<LogicalKeySet, Intent>> { |
|||
|
|||
public ShortcutMapProperty( |
|||
string name, |
|||
Dictionary<LogicalKeySet, Intent> value, |
|||
bool showName = true, |
|||
Object defaultValue = null,//foundation_.kNoDefaultValue
|
|||
DiagnosticLevel level = DiagnosticLevel.info, |
|||
string description = null |
|||
) : base( |
|||
name: name, |
|||
value: value, |
|||
showName: showName, |
|||
defaultValue: defaultValue, |
|||
level: level, |
|||
description: description |
|||
) |
|||
{ |
|||
D.assert(showName != null); |
|||
D.assert(level != null); |
|||
} |
|||
|
|||
|
|||
protected override string valueToString( TextTreeConfiguration parentConfiguration = null) { |
|||
List<string> res = new List<string>(); |
|||
foreach (var key in value.Keys) { |
|||
string temp = "{" + key.debugDescribeKeys() + "}:" + value[key]; |
|||
res.Add(temp); |
|||
} |
|||
return string.Join(", ", res); |
|||
} |
|||
} |
|||
|
|||
public class ShortcutManager : DiagnosticableMixinChangeNotifier { |
|||
|
|||
public ShortcutManager( |
|||
Dictionary<LogicalKeySet, Intent> shortcuts = null, |
|||
bool modal = false |
|||
) { |
|||
shortcuts = shortcuts ?? new Dictionary<LogicalKeySet, Intent>(); |
|||
D.assert(shortcuts != null); |
|||
this.modal = modal; |
|||
this.shortcuts = shortcuts; |
|||
} |
|||
|
|||
/// True if the [ShortcutManager] should not pass on keys that it doesn't
|
|||
/// handle to any key-handling widgets that are ancestors to this one.
|
|||
///
|
|||
/// Setting [modal] to true is the equivalent of always handling any key given
|
|||
/// to it, even if that key doesn't appear in the [shortcuts] map. Keys that
|
|||
/// don't appear in the map will be dropped.
|
|||
public readonly bool modal; |
|||
|
|||
|
|||
Dictionary<LogicalKeySet, Intent> _shortcuts; |
|||
|
|||
public Dictionary<LogicalKeySet, Intent> shortcuts { |
|||
get { return _shortcuts; } |
|||
set { |
|||
_shortcuts = value; |
|||
notifyListeners(); |
|||
} |
|||
} |
|||
|
|||
/// Handles a key pressed `event` in the given `context`.
|
|||
///
|
|||
/// The optional `keysPressed` argument provides an override to keys that the
|
|||
/// [RawKeyboard] reports. If not specified, uses [RawKeyboard.keysPressed]
|
|||
/// instead.
|
|||
public bool handleKeypress( |
|||
BuildContext context, |
|||
RawKeyEvent rawKeyEvent, |
|||
LogicalKeySet keysPressed = null |
|||
) { |
|||
if (!(rawKeyEvent is RawKeyDownEvent)) { |
|||
return false; |
|||
} |
|||
D.assert(context != null); |
|||
LogicalKeySet keySet = keysPressed ?? new LogicalKeySet(RawKeyboard.instance.keysPressed); |
|||
Intent matchedIntent = _shortcuts[keySet]; |
|||
if (matchedIntent == null) { |
|||
// If there's not a more specific match, We also look for any keys that
|
|||
// have synonyms in the map. This is for things like left and right shift
|
|||
// keys mapping to just the "shift" pseudo-key.
|
|||
HashSet<LogicalKeyboardKey> pseudoKeys = new HashSet<LogicalKeyboardKey>{}; |
|||
foreach (LogicalKeyboardKey setKey in keySet.keys) { |
|||
HashSet<LogicalKeyboardKey> synonyms = setKey.synonyms; |
|||
if (synonyms.isNotEmpty()) { |
|||
// There currently aren't any synonyms that match more than one key.
|
|||
pseudoKeys.Add(synonyms.First()); |
|||
} else { |
|||
pseudoKeys.Add(setKey); |
|||
} |
|||
} |
|||
matchedIntent = _shortcuts[new LogicalKeySet(pseudoKeys)]; |
|||
} |
|||
if (matchedIntent != null) { |
|||
BuildContext primaryContext = FocusManagerUtils.primaryFocus?.context; |
|||
if (primaryContext == null) { |
|||
return false; |
|||
} |
|||
return Actions.invoke(primaryContext, matchedIntent, nullOk: true); |
|||
} |
|||
return false; |
|||
} |
|||
|
|||
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|||
base.debugFillProperties(properties: properties); |
|||
properties.add(new DiagnosticsProperty<Dictionary<LogicalKeySet, Intent>>("shortcuts", _shortcuts)); |
|||
properties.add(new FlagProperty("modal", value: modal, ifTrue: "modal", defaultValue: false)); |
|||
} |
|||
} |
|||
|
|||
public class Shortcuts : StatefulWidget { |
|||
/// Creates a ActionManager object.
|
|||
///
|
|||
/// The [child] argument must not be null.
|
|||
public Shortcuts( |
|||
Key key = null, |
|||
ShortcutManager manager = null, |
|||
Dictionary<LogicalKeySet, Intent> shortcuts = null, |
|||
Widget child = null, |
|||
string debugLabel = null |
|||
) : base(key: key) { |
|||
this.manager = manager; |
|||
this.shortcuts = shortcuts; |
|||
this.child = child; |
|||
this.debugLabel = debugLabel; |
|||
} |
|||
|
|||
public readonly ShortcutManager manager; |
|||
|
|||
public readonly Dictionary<LogicalKeySet, Intent> shortcuts; |
|||
|
|||
public readonly Widget child; |
|||
|
|||
public readonly string debugLabel; |
|||
|
|||
public static ShortcutManager of(BuildContext context, bool nullOk = false) { |
|||
D.assert(context != null); |
|||
_ShortcutsMarker inherited = context.dependOnInheritedWidgetOfExactType<_ShortcutsMarker>(); |
|||
D.assert(() => { |
|||
if (nullOk) { |
|||
return true; |
|||
} |
|||
if (inherited == null) { |
|||
throw new UIWidgetsError($"Unable to find a {typeof(Shortcuts)} widget in the context.\n" + |
|||
$"{typeof(Shortcuts)}.of()was called with a context that does not contain a " + |
|||
$"{typeof(Shortcuts)} widget.\n" + |
|||
$"No {typeof(Shortcuts)} ancestor could be found starting from the context that was " + |
|||
$"passed to {typeof(Shortcuts)}.of().\n" + |
|||
"The context used was:\n" + |
|||
$" {context}"); |
|||
} |
|||
return true; |
|||
}); |
|||
return inherited?.notifier; |
|||
} |
|||
|
|||
|
|||
public override State createState() { |
|||
return new _ShortcutsState(); |
|||
} |
|||
|
|||
|
|||
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|||
base.debugFillProperties(properties); |
|||
properties.add(new DiagnosticsProperty<ShortcutManager>("manager", manager, defaultValue: null)); |
|||
properties.add(new ShortcutMapProperty("shortcuts", shortcuts, description: debugLabel?.isNotEmpty() ?? false ? debugLabel : null)); |
|||
} |
|||
} |
|||
|
|||
public class _ShortcutsState : State<Shortcuts> { |
|||
|
|||
private ShortcutManager _internalManager; |
|||
public ShortcutManager manager { |
|||
get { return widget.manager ?? _internalManager; } |
|||
} |
|||
|
|||
|
|||
public override void dispose() { |
|||
_internalManager?.dispose(); |
|||
base.dispose(); |
|||
} |
|||
|
|||
|
|||
public override void initState() { |
|||
base.initState(); |
|||
if (widget.manager == null) { |
|||
_internalManager = new ShortcutManager(); |
|||
} |
|||
manager.shortcuts = widget.shortcuts; |
|||
} |
|||
|
|||
|
|||
public override void didUpdateWidget(StatefulWidget oldWidget) { |
|||
base.didUpdateWidget((Shortcuts)oldWidget); |
|||
if (widget.manager != ((Shortcuts)oldWidget).manager) { |
|||
if (widget.manager != null) { |
|||
_internalManager?.dispose(); |
|||
_internalManager = null; |
|||
} else { |
|||
_internalManager = _internalManager?? new ShortcutManager(); |
|||
} |
|||
} |
|||
manager.shortcuts = widget.shortcuts; |
|||
} |
|||
|
|||
public bool _handleOnKey(FocusNode node, RawKeyEvent _event) |
|||
{ |
|||
if (node.context == null) { |
|||
return false; |
|||
} |
|||
return manager.handleKeypress(node.context, _event) || manager.modal; |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
return new Focus( |
|||
debugLabel: typeof(Shortcuts).ToString(), |
|||
canRequestFocus: false, |
|||
onKey: _handleOnKey, |
|||
child: new _ShortcutsMarker( |
|||
manager: manager, |
|||
child: widget.child |
|||
) |
|||
); |
|||
} |
|||
} |
|||
|
|||
public class _ShortcutsMarker : InheritedNotifier<ShortcutManager> { |
|||
public _ShortcutsMarker( |
|||
ShortcutManager manager = null, |
|||
Widget child = null |
|||
) : base(notifier: manager, child: child) { |
|||
D.assert(manager != null); |
|||
D.assert(child != null); |
|||
} |
|||
} |
|||
|
|||
} |
|
|||
using System; |
|||
using System.Collections.Generic; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.scheduler2; |
|||
using Unity.UIWidgets.ui; |
|||
using Unity.UIWidgets.service; |
|||
namespace Unity.UIWidgets.widgets { |
|||
class Title : StatelessWidget { |
|||
public Title( |
|||
Color color, |
|||
Key key = null, |
|||
string title = "", |
|||
Widget child = null |
|||
) : base(key: key) { |
|||
D.assert(title != null); |
|||
D.assert(color != null && color.alpha == 0xFF); |
|||
} |
|||
|
|||
public readonly String title; |
|||
public readonly Color color; |
|||
public readonly Widget child; |
|||
public override Widget build(BuildContext context) { |
|||
/*SystemChrome.setApplicationSwitcherDescription( |
|||
new ApplicationSwitcherDescription( |
|||
label: title, |
|||
primaryColor: (int)color.value |
|||
) |
|||
);*/ |
|||
return child; |
|||
} |
|||
public override void debugFillProperties(DiagnosticPropertiesBuilder properties) { |
|||
base.debugFillProperties(properties); |
|||
properties.add(new StringProperty("title", title, defaultValue: "")); |
|||
//properties.add(new ColorProperty("color", color, defaultValue: null));
|
|||
} |
|||
} |
|||
|
|||
} |
|
|||
using System; |
|||
using Unity.UIWidgets.animation; |
|||
using Unity.UIWidgets.foundation; |
|||
using Unity.UIWidgets.ui; |
|||
|
|||
namespace Unity.UIWidgets.widgets { |
|||
public class TweenAnimationBuilder<T> : ImplicitlyAnimatedWidget { |
|||
public TweenAnimationBuilder( |
|||
Key key = null, |
|||
Tween<T> tween = null, |
|||
TimeSpan? duration = null, |
|||
Curve curve = null, |
|||
ValueWidgetBuilder<T> builder = null, |
|||
VoidCallback onEnd = null, |
|||
Widget child = null |
|||
) : base(key: key, duration: duration, curve: curve, onEnd: onEnd) { |
|||
curve = curve ?? Curves.linear; |
|||
D.assert(tween != null); |
|||
D.assert(curve != null); |
|||
D.assert(builder != null); |
|||
} |
|||
|
|||
|
|||
public readonly Tween<T> tween; |
|||
public readonly ValueWidgetBuilder<T> builder; |
|||
public readonly Widget child; |
|||
public override State createState() { |
|||
return new _TweenAnimationBuilderState<T>(); |
|||
} |
|||
} |
|||
public class _TweenAnimationBuilderState<T> : AnimatedWidgetBaseState<TweenAnimationBuilder<T>> { |
|||
Tween<T> _currentTween; |
|||
|
|||
public override void initState() { |
|||
_currentTween = widget.tween; |
|||
if (_currentTween.begin == null) { |
|||
_currentTween.begin = _currentTween.end; |
|||
} |
|||
|
|||
|
|||
base.initState(); |
|||
if (_currentTween.begin.Equals( _currentTween.end)) { |
|||
controller.forward(); |
|||
} |
|||
} |
|||
|
|||
protected override void forEachTween(TweenVisitor visitor) { |
|||
D.assert( |
|||
widget.tween.end != null,()=> |
|||
"Tween provided to TweenAnimationBuilder must have non-null Tween.end value."); |
|||
_currentTween = visitor.visit( |
|||
this, |
|||
_currentTween, |
|||
widget.tween.end, |
|||
(value) =>{ |
|||
D.assert(false); |
|||
return null; }) as Tween<T>; |
|||
} |
|||
|
|||
public override Widget build(BuildContext context) { |
|||
return widget.builder(context, _currentTween.evaluate(animation), widget.child); |
|||
} |
|||
} |
|||
|
|||
} |
|
|||
using Unity.UIWidgets.foundation; |
|||
|
|||
namespace Unity.UIWidgets.widgets { |
|||
public abstract class UniqueWidget<T> :StatefulWidget where T: State<StatefulWidget> { |
|||
|
|||
public UniqueWidget( |
|||
GlobalKey<T> key |
|||
) : base(key: key) { |
|||
D.assert(key != null); |
|||
} |
|||
public abstract override State createState(); |
|||
|
|||
T currentState { |
|||
get { |
|||
GlobalKey<T> globalKey = key as GlobalKey<T>; |
|||
return globalKey.currentState; |
|||
} |
|||
} |
|||
} |
|||
|
|||
} |
撰写
预览
正在加载...
取消
保存
Reference in new issue