Browse Source

Merge pull request #73 from memspace/render-context-fix

Fix for updating dirty state of render boxes when re-attached
Anatoly Pulyaevskiy 6 years ago
parent
commit
e028e112e3
No account linked to committer's email address

+ 5
- 0
packages/zefyr/lib/src/widgets/editable_box.dart View File

@@ -77,6 +77,8 @@ class RenderEditableProxyBox extends RenderBox
77 77
     this.child = child;
78 78
   }
79 79
 
80
+  bool _isDirty = true;
81
+
80 82
   ContainerNode get node => _node;
81 83
   ContainerNode _node;
82 84
   void set node(ContainerNode value) {
@@ -155,6 +157,7 @@ class RenderEditableProxyBox extends RenderBox
155 157
     super.attach(owner);
156 158
     _showCursor.addListener(markNeedsPaint);
157 159
     _renderContext.addBox(this);
160
+    _renderContext.markDirty(this, _isDirty);
158 161
   }
159 162
 
160 163
   @override
@@ -171,12 +174,14 @@ class RenderEditableProxyBox extends RenderBox
171 174
     _caretPainter.layout(preferredLineHeight);
172 175
     // Indicate to render context that this object can be used by other
173 176
     // layers (selection overlay, for instance).
177
+    _isDirty = false;
174 178
     _renderContext.markDirty(this, false);
175 179
   }
176 180
 
177 181
   @override
178 182
   void markNeedsLayout() {
179 183
     // Temporarily remove this object from the render context.
184
+    _isDirty = true;
180 185
     _renderContext.markDirty(this, true);
181 186
     super.markNeedsLayout();
182 187
   }

+ 1
- 0
packages/zefyr/lib/src/widgets/render_context.dart View File

@@ -102,6 +102,7 @@ class ZefyrRenderContext extends ChangeNotifier {
102 102
   /// the active boxes. If it is then that box is returned.
103 103
   RenderEditableProxyBox closestBoxForGlobalPoint(Offset point) {
104 104
     assert(!_disposed);
105
+    if (_activeBoxes.isEmpty) return null;
105 106
     RenderEditableProxyBox box = boxForGlobalPoint(point);
106 107
     if (box != null) return box;
107 108
 

+ 0
- 41
packages/zefyr/test/rendering/render_editable_paragraph_test.dart View File

@@ -1,41 +0,0 @@
1
-// Copyright (c) 2018, the Zefyr project authors.  Please see the AUTHORS file
2
-// for details. All rights reserved. Use of this source code is governed by a
3
-// BSD-style license that can be found in the LICENSE file.
4
-import 'dart:ui';
5
-
6
-import 'package:flutter/material.dart';
7
-import 'package:flutter/rendering.dart';
8
-import 'package:flutter_test/flutter_test.dart';
9
-import 'package:zefyr/src/widgets/render_context.dart';
10
-import 'package:zefyr/src/widgets/rich_text.dart';
11
-import 'package:zefyr/zefyr.dart';
12
-
13
-void main() {
14
-  group('$RenderEditableParagraph', () {
15
-    final doc = new NotusDocument();
16
-    doc.insert(0, 'This House Is A Circus');
17
-    final text = new TextSpan(text: 'This House Is A Circus');
18
-
19
-    ZefyrRenderContext renderContext;
20
-    RenderEditableParagraph p;
21
-
22
-    setUp(() {
23
-      WidgetsFlutterBinding.ensureInitialized();
24
-      renderContext = new ZefyrRenderContext();
25
-      p = new RenderEditableParagraph(
26
-        text,
27
-        node: doc.root.children.first,
28
-        textDirection: TextDirection.ltr,
29
-      );
30
-    });
31
-
32
-    test('it registers with viewport', () {
33
-      var owner = new PipelineOwner();
34
-      expect(renderContext.active, isNot(contains(p)));
35
-      p.attach(owner);
36
-      expect(renderContext.dirty, contains(p));
37
-      p.layout(new BoxConstraints());
38
-      expect(renderContext.active, contains(p));
39
-    }, skip: 'TODO: move to RenderEditableProxyBox');
40
-  });
41
-}

+ 63
- 0
packages/zefyr/test/rendering/render_editable_proxy_box_test.dart View File

@@ -0,0 +1,63 @@
1
+// Copyright (c) 2018, the Zefyr project authors.  Please see the AUTHORS file
2
+// for details. All rights reserved. Use of this source code is governed by a
3
+// BSD-style license that can be found in the LICENSE file.
4
+import 'dart:ui';
5
+
6
+import 'package:flutter/material.dart';
7
+import 'package:flutter/rendering.dart';
8
+import 'package:flutter_test/flutter_test.dart';
9
+import 'package:zefyr/src/widgets/editable_box.dart';
10
+import 'package:zefyr/src/widgets/render_context.dart';
11
+import 'package:zefyr/src/widgets/rich_text.dart';
12
+import 'package:zefyr/zefyr.dart';
13
+
14
+void main() {
15
+  group('$RenderEditableProxyBox', () {
16
+    final doc = NotusDocument();
17
+    doc.insert(0, 'This House Is A Circus');
18
+    final text = TextSpan(text: 'This House Is A Circus');
19
+
20
+    ZefyrRenderContext renderContext;
21
+    RenderEditableProxyBox p;
22
+
23
+    setUp(() {
24
+      WidgetsFlutterBinding.ensureInitialized();
25
+      renderContext = ZefyrRenderContext();
26
+      final rt = RenderEditableParagraph(
27
+        text,
28
+        node: doc.root.children.first,
29
+        textDirection: TextDirection.ltr,
30
+      );
31
+      p = RenderEditableProxyBox(
32
+        child: rt,
33
+        node: doc.root.children.first,
34
+        layerLink: LayerLink(),
35
+        renderContext: renderContext,
36
+        showCursor: ValueNotifier<bool>(true),
37
+        selection: TextSelection.collapsed(offset: 0),
38
+        selectionColor: Color(0),
39
+      );
40
+    });
41
+
42
+    test('it registers with render context', () {
43
+      var owner = new PipelineOwner();
44
+      expect(renderContext.active, isNot(contains(p)));
45
+      p.attach(owner);
46
+      expect(renderContext.dirty, contains(p));
47
+      p.layout(BoxConstraints());
48
+      expect(renderContext.active, contains(p));
49
+
50
+      p.detach();
51
+      expect(renderContext.active, isNot(contains(p)));
52
+      p.attach(owner);
53
+      expect(renderContext.active, contains(p));
54
+
55
+      p.markNeedsLayout();
56
+      p.detach();
57
+      expect(renderContext.active, isNot(contains(p)));
58
+
59
+      p.layout(BoxConstraints());
60
+      expect(renderContext.active, contains(p));
61
+    });
62
+  });
63
+}