Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1807)

Side by Side Diff: runtime/observatory/lib/src/elements/containers/virtual_collection.dart

Issue 2203433002: Added new implementations for virtual containers (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Added new files to observatory_sources.gypi Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2016, the Dart 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
5 import 'dart:async';
6 import 'dart:html';
7 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
8 import 'package:observatory/src/elements/helpers/tag.dart';
9
10 typedef HtmlElement CreateElementCallback();
11 typedef void UpdateElementCallback(HtmlElement el, dynamic item, int index);
12
13 class VirtualCollectionElement extends HtmlElement implements Renderable {
14 static const tag =
15 const Tag<VirtualCollectionElement>('virtual-collection');
16
17 RenderingScheduler<VirtualCollectionElement> _r;
18
19 Stream<RenderedEvent<VirtualCollectionElement>> get onRendered => _r.onRendere d;
20
21 CreateElementCallback _create;
22 UpdateElementCallback _update;
23 double _itemHeight;
24 int _top;
25 int _height;
26 List _items;
27 StreamSubscription _onScrollSubscription;
28 StreamSubscription _onResizeSubscription;
29
30 List get items => _items;
31
32 set items(Iterable value) {
33 _items = new List.unmodifiable(value);
34 _r.dirty();
35 }
36
37
38 factory VirtualCollectionElement(CreateElementCallback create,
39 UpdateElementCallback update, {Iterable items: const [],
40 RenderingQueue queue}) {
41 assert(create != null);
42 assert(update != null);
43 assert(items != null);
44 VirtualCollectionElement e = document.createElement(tag.name);
45 e._r = new RenderingScheduler(e, queue: queue);
46 e._create = create;
47 e._update = update;
48 e._items = new List.unmodifiable(items);
49 return e;
50 }
51
52 VirtualCollectionElement.created() : super.created();
53
54 @override
55 attached() {
56 super.attached();
57 _r.enable();
58 _top = 0;
59 _height = getBoundingClientRect().height;
60 _itemHeight = _computeItemHeight();
61 _onScrollSubscription = onScroll.listen(_onScroll);
62 _onResizeSubscription = window.onResize.listen(_onResize);
63 }
64
65 @override
66 detached() {
67 super.detached();
68 _r.disable(notify: true);
69 children = const [];
70 _onScrollSubscription.cancel();
71 _onResizeSubscription.cancel();
72 }
73
74 final DivElement _scroller = new DivElement()..classes = const ['scroller'];
75 final DivElement _shifter = new DivElement()..classes = const ['shifter'];
76
77 dynamic getItemFromElement(HtmlElement element) {
78 final el_index = _shifter.children.indexOf(element);
79 if (el_index < 0) {
80 return null;
81 }
82 final item_index = _top + el_index - (_shifter.children.length / 4).floor();
83 if (0 <= item_index && item_index < items.length){
turnidge 2016/08/01 21:13:10 Add space before {
cbernaschina 2016/08/01 21:48:12 Done.
84 return _items[item_index];
85 }
86 return null;
87 }
88
89 /// The preloaded element before and after the visible area are:
90 /// 1/preload_size of the number of items in the visble area.
91 /// See shared.css for the "top:-25%;".
92 static const int _preload = 2;
93 /// L = length of all the elements loaded
94 /// l = length of the visible area
95 ///
96 /// L = l + 2 * l / _preload
97 /// l = L * _preload / (_preload + 2)
98 ///
99 /// tail = l / _preload = L * 1 / (_preload + 2) = L * _inverse_preload
100 static const double _inverse_preload = 1 / (_preload + 2);
101
102 void render() {
103 _top = (scrollTop / _itemHeight).floor();
104
105 _scroller.style.height = '${_itemHeight*(_items.length)}px';
106 _shifter.style.top = '${_itemHeight*_top}px';
107 final tail_length = (_height / _itemHeight / _preload).ceil();
108 final length = tail_length * 2 + tail_length * _preload;
109
110 if (_shifter.children.length < length) {
111 while (_shifter.children.length != length) {
112 var e = _create();
113 e..style.display = 'hidden';
114 _shifter.children.add(e);
115 }
116 _shifter.style.height = '${_itemHeight*length}px';
117 children = [
118 _scroller
119 ..children = [_shifter]
120 ];
121 }
122
123 int i = _top - tail_length;
124 for (final HtmlElement e in _shifter.children) {
125 if (0 <= i && i < _items.length) {
126 e..style.display = null;
127 _update(e, _items[i], i);
128 } else {
129 e.style.display = 'hidden';
130 }
131 i++;
132 }
133 }
134
135 double _computeItemHeight() {
136 final c = children;
137 children = [_create()];
138 final height = children[0].getBoundingClientRect().height;
139 children = c;
140 return height;
141 }
142
143 void _onScroll(_) {
144 if(_r.isDirty) return;
145 if ((scrollTop - _top * _itemHeight).abs() >=
146 _shifter.children.length * _inverse_preload * _itemHeight) {
147 _r.dirty();
148 }
149 }
150
151 void _onResize(_) {
152 _height = getBoundingClientRect().height;
153 _r.dirty();
154 }
155 }
OLDNEW
« no previous file with comments | « runtime/observatory/lib/elements.dart ('k') | runtime/observatory/lib/src/elements/containers/virtual_tree.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698