Skip to content

Commit

Permalink
Add ignoringSemantics argument to AbsorbPointer (flutter#19651)
Browse files Browse the repository at this point in the history
  • Loading branch information
jonahwilliams authored Jul 23, 2018
1 parent b4d3808 commit d61b4fa
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 6 deletions.
46 changes: 44 additions & 2 deletions packages/flutter/lib/src/rendering/proxy_box.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2881,16 +2881,45 @@ class RenderAbsorbPointer extends RenderProxyBox {
/// The [absorbing] argument must not be null.
RenderAbsorbPointer({
RenderBox child,
this.absorbing = true
bool absorbing = true,
bool ignoringSemantics,
}) : assert(absorbing != null),
_absorbing = absorbing,
_ignoringSemantics = ignoringSemantics,
super(child);

/// Whether this render object absorbs pointers during hit testing.
///
/// Regardless of whether this render object absorbs pointers during hit
/// testing, it will still consume space during layout and be visible during
/// painting.
bool absorbing;
bool get absorbing => _absorbing;
bool _absorbing;
set absorbing(bool value) {
if (_absorbing == value)
return;
_absorbing = value;
if (ignoringSemantics == null)
markNeedsSemanticsUpdate();
}

/// Whether the semantics of this render object is ignored when compiling the semantics tree.
///
/// If null, defaults to value of [absorbing].
///
/// See [SemanticsNode] for additional information about the semantics tree.
bool get ignoringSemantics => _ignoringSemantics;
bool _ignoringSemantics;
set ignoringSemantics(bool value) {
if (value == _ignoringSemantics)
return;
final bool oldEffectiveValue = _effectiveIgnoringSemantics;
_ignoringSemantics = value;
if (oldEffectiveValue != _effectiveIgnoringSemantics)
markNeedsSemanticsUpdate();
}

bool get _effectiveIgnoringSemantics => ignoringSemantics == null ? absorbing : ignoringSemantics;

@override
bool hitTest(HitTestResult result, { Offset position }) {
Expand All @@ -2899,10 +2928,23 @@ class RenderAbsorbPointer extends RenderProxyBox {
: super.hitTest(result, position: position);
}

@override
void visitChildrenForSemantics(RenderObjectVisitor visitor) {
if (child != null && !_effectiveIgnoringSemantics)
visitor(child);
}

@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<bool>('absorbing', absorbing));
properties.add(
new DiagnosticsProperty<bool>(
'ignoringSemantics',
_effectiveIgnoringSemantics,
description: ignoringSemantics == null ? 'implicitly $_effectiveIgnoringSemantics' : null,
),
);
}
}

Expand Down
29 changes: 26 additions & 3 deletions packages/flutter/lib/src/widgets/basic.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4949,7 +4949,8 @@ class AbsorbPointer extends SingleChildRenderObjectWidget {
const AbsorbPointer({
Key key,
this.absorbing = true,
Widget child
Widget child,
this.ignoringSemantics,
}) : assert(absorbing != null),
super(key: key, child: child);

Expand All @@ -4960,12 +4961,34 @@ class AbsorbPointer extends SingleChildRenderObjectWidget {
/// painting.
final bool absorbing;

/// Whether the semantics of this render object is ignored when compiling the
/// semantics tree.
///
/// If null, defaults to the value of [absorbing].
///
/// See [SemanticsNode] for additional information about the semantics tree.
final bool ignoringSemantics;

@override
RenderAbsorbPointer createRenderObject(BuildContext context) => new RenderAbsorbPointer(absorbing: absorbing);
RenderAbsorbPointer createRenderObject(BuildContext context) {
return new RenderAbsorbPointer(
absorbing: absorbing,
ignoringSemantics: ignoringSemantics,
);
}

@override
void updateRenderObject(BuildContext context, RenderAbsorbPointer renderObject) {
renderObject.absorbing = absorbing;
renderObject
..absorbing = absorbing
..ignoringSemantics = ignoringSemantics;
}

@override
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(new DiagnosticsProperty<bool>('absorbing', absorbing));
properties.add(new DiagnosticsProperty<bool>('ignoringSemantics', ignoringSemantics, defaultValue: null));
}
}

Expand Down
41 changes: 40 additions & 1 deletion packages/flutter/test/widgets/absorb_pointer_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/widgets.dart';

import 'semantics_tester.dart';

void main() {
testWidgets('AbsorbPointers do not block siblings', (WidgetTester tester) async {
bool tapped = false;
Expand All @@ -28,4 +30,41 @@ void main() {
await tester.tap(find.byType(GestureDetector));
expect(tapped, true);
});
}

testWidgets('AbsorbPointers semantics', (WidgetTester tester) async {
final SemanticsTester semantics = new SemanticsTester(tester);
await tester.pumpWidget(
new AbsorbPointer(
absorbing: true,
child: new Semantics(
label: 'test',
textDirection: TextDirection.ltr,
),
),
);
expect(semantics, hasSemantics(
new TestSemantics.root(), ignoreId: true, ignoreRect: true, ignoreTransform: true));

await tester.pumpWidget(
new AbsorbPointer(
absorbing: false,
child: new Semantics(
label: 'test',
textDirection: TextDirection.ltr,
),
),
);

expect(semantics, hasSemantics(
new TestSemantics.root(
children: <TestSemantics>[
new TestSemantics.rootChild(
label: 'test',
textDirection: TextDirection.ltr,
),
],
),
ignoreId: true, ignoreRect: true, ignoreTransform: true));
semantics.dispose();
});
}

0 comments on commit d61b4fa

Please sign in to comment.