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

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

Issue 2255613002: Converted Observatory heap-profile element (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Better sorting tests 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
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file 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 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. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 import 'dart:async'; 5 import 'dart:async';
6 import 'dart:html'; 6 import 'dart:html';
7 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart'; 7 import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
8 import 'package:observatory/src/elements/helpers/tag.dart'; 8 import 'package:observatory/src/elements/helpers/tag.dart';
9 9
10 typedef HtmlElement VirtualCollectionCreateCallback(); 10 typedef HtmlElement VirtualCollectionCreateCallback();
11 typedef void VirtualCollectionUpdateCallback(HtmlElement el, dynamic item, 11 typedef void VirtualCollectionUpdateCallback(HtmlElement el, dynamic item,
12 int index); 12 int index);
13 13
14 class VirtualCollectionElement extends HtmlElement implements Renderable { 14 class VirtualCollectionElement extends HtmlElement implements Renderable {
15 static const tag = 15 static const tag =
16 const Tag<VirtualCollectionElement>('virtual-collection'); 16 const Tag<VirtualCollectionElement>('virtual-collection');
17 17
18 RenderingScheduler<VirtualCollectionElement> _r; 18 RenderingScheduler<VirtualCollectionElement> _r;
19 19
20 Stream<RenderedEvent<VirtualCollectionElement>> get onRendered => 20 Stream<RenderedEvent<VirtualCollectionElement>> get onRendered =>
21 _r.onRendered; 21 _r.onRendered;
22 22
23 VirtualCollectionCreateCallback _create; 23 VirtualCollectionCreateCallback _create;
24 VirtualCollectionCreateCallback _createHeader;
24 VirtualCollectionUpdateCallback _update; 25 VirtualCollectionUpdateCallback _update;
25 double _itemHeight; 26 double _itemHeight;
26 int _top; 27 int _top;
27 double _height; 28 double _height;
28 List _items; 29 List _items;
29 StreamSubscription _onScrollSubscription; 30 StreamSubscription _onScrollSubscription;
30 StreamSubscription _onResizeSubscription; 31 StreamSubscription _onResizeSubscription;
31 32
32 List get items => _items; 33 List get items => _items;
33 34
34 set items(Iterable value) { 35 set items(Iterable value) {
35 _items = new List.unmodifiable(value); 36 _items = new List.unmodifiable(value);
37 _top = null;
36 _r.dirty(); 38 _r.dirty();
37 } 39 }
38 40
39 41
40 factory VirtualCollectionElement(VirtualCollectionCreateCallback create, 42 factory VirtualCollectionElement(VirtualCollectionCreateCallback create,
41 VirtualCollectionUpdateCallback update, {Iterable items: const [], 43 VirtualCollectionUpdateCallback update, {Iterable items: const [],
44 VirtualCollectionCreateCallback createHeader,
42 RenderingQueue queue}) { 45 RenderingQueue queue}) {
43 assert(create != null); 46 assert(create != null);
44 assert(update != null); 47 assert(update != null);
45 assert(items != null); 48 assert(items != null);
46 VirtualCollectionElement e = document.createElement(tag.name); 49 VirtualCollectionElement e = document.createElement(tag.name);
47 e._r = new RenderingScheduler(e, queue: queue); 50 e._r = new RenderingScheduler(e, queue: queue);
48 e._create = create; 51 e._create = create;
52 e._createHeader = createHeader;
49 e._update = update; 53 e._update = update;
50 e._items = new List.unmodifiable(items); 54 e._items = new List.unmodifiable(items);
51 return e; 55 return e;
52 } 56 }
53 57
54 VirtualCollectionElement.created() : super.created(); 58 VirtualCollectionElement.created() : super.created();
55 59
56 @override 60 @override
57 attached() { 61 attached() {
58 super.attached(); 62 super.attached();
59 _r.enable(); 63 _r.enable();
60 _top = 0; 64 _top = null;
61 _height = getBoundingClientRect().height; 65 _itemHeight = null;
62 _itemHeight = _computeItemHeight();
63 _onScrollSubscription = onScroll.listen(_onScroll); 66 _onScrollSubscription = onScroll.listen(_onScroll);
64 _onResizeSubscription = window.onResize.listen(_onResize); 67 _onResizeSubscription = window.onResize.listen(_onResize);
65 } 68 }
66 69
67 @override 70 @override
68 detached() { 71 detached() {
69 super.detached(); 72 super.detached();
70 _r.disable(notify: true); 73 _r.disable(notify: true);
71 children = const []; 74 children = const [];
72 _onScrollSubscription.cancel(); 75 _onScrollSubscription.cancel();
73 _onResizeSubscription.cancel(); 76 _onResizeSubscription.cancel();
74 } 77 }
75 78
79 final DivElement _header = new DivElement()..classes = const ['header'];
76 final DivElement _scroller = new DivElement()..classes = const ['scroller']; 80 final DivElement _scroller = new DivElement()..classes = const ['scroller'];
77 final DivElement _shifter = new DivElement()..classes = const ['shifter']; 81 final DivElement _shifter = new DivElement()..classes = const ['shifter'];
78 82
79 dynamic getItemFromElement(HtmlElement element) { 83 dynamic getItemFromElement(HtmlElement element) {
80 final el_index = _shifter.children.indexOf(element); 84 final el_index = _shifter.children.indexOf(element);
81 if (el_index < 0) { 85 if (el_index < 0) {
82 return null; 86 return null;
83 } 87 }
84 final item_index = 88 final item_index =
85 _top + el_index - (_shifter.children.length * _inverse_preload).floor(); 89 _top + el_index - (_shifter.children.length * _inverse_preload).floor();
(...skipping 10 matching lines...) Expand all
96 /// L = length of all the elements loaded 100 /// L = length of all the elements loaded
97 /// l = length of the visible area 101 /// l = length of the visible area
98 /// 102 ///
99 /// L = l + 2 * l / _preload 103 /// L = l + 2 * l / _preload
100 /// l = L * _preload / (_preload + 2) 104 /// l = L * _preload / (_preload + 2)
101 /// 105 ///
102 /// tail = l / _preload = L * 1 / (_preload + 2) = L * _inverse_preload 106 /// tail = l / _preload = L * 1 / (_preload + 2) = L * _inverse_preload
103 static const double _inverse_preload = 1 / (_preload + 2); 107 static const double _inverse_preload = 1 / (_preload + 2);
104 108
105 void render() { 109 void render() {
106 _top = (scrollTop / _itemHeight).floor(); 110 if (children.isEmpty) {
111 children = [
112 _scroller
113 ..children = [
114 _shifter
115 ..children = [_create()]
116 ],
117 ];
118 if (_createHeader != null) {
119 _header.children = [_createHeader()];
120 _scroller.children.insert(0, _header);
121 }
122 _itemHeight = _shifter.children[0].getBoundingClientRect().height;
123 _height = getBoundingClientRect().height;
124 }
125 final top = (scrollTop / _itemHeight).floor();
107 126
127 _header.style.top = '${scrollTop}px';
108 _scroller.style.height = '${_itemHeight*(_items.length)}px'; 128 _scroller.style.height = '${_itemHeight*(_items.length)}px';
109 final tail_length = (_height / _itemHeight / _preload).ceil(); 129 final tail_length = (_height / _itemHeight / _preload).ceil();
110 _shifter.style.top = '${_itemHeight*(_top - tail_length)}px';
111 final length = tail_length * 2 + tail_length * _preload; 130 final length = tail_length * 2 + tail_length * _preload;
112 131
113 if (_shifter.children.length < length) { 132 if (_shifter.children.length < length) {
114 while (_shifter.children.length != length) { 133 while (_shifter.children.length != length) {
115 var e = _create(); 134 var e = _create();
116 e..style.display = 'hidden'; 135 e..style.display = 'hidden';
117 _shifter.children.add(e); 136 _shifter.children.add(e);
118 } 137 }
119 children = [ 138 _top = null; // force update;
120 _scroller
121 ..children = [_shifter]
122 ];
123 } 139 }
124 140
125 int i = _top - tail_length; 141 if ((_top == null) || ((top - _top).abs() >= tail_length)) {
126 for (final HtmlElement e in _shifter.children) { 142 _shifter.style.top = '${_itemHeight*(top-tail_length)}px';
127 if (0 <= i && i < _items.length) { 143 int i = top - tail_length;
128 e..style.display = null; 144 for (final HtmlElement e in _shifter.children) {
129 _update(e, _items[i], i); 145 if (0 <= i && i < _items.length) {
130 } else { 146 e..style.display = null;
131 e.style.display = 'hidden'; 147 _update(e, _items[i], i);
148 } else {
149 e.style.display = 'hidden';
150 }
151 i++;
132 } 152 }
133 i++; 153 _top = top;
134 } 154 }
135 } 155 }
136 156
137 double _computeItemHeight() {
138 final c = children;
139 children = [_create()];
140 final height = children[0].getBoundingClientRect().height;
141 children = c;
142 return height;
143 }
144
145 void _onScroll(_) { 157 void _onScroll(_) {
146 if(_r.isDirty) return; 158 _r.dirty();
147 if ((scrollTop - _top * _itemHeight).abs() >=
148 _shifter.children.length * _inverse_preload * _itemHeight) {
149 _r.dirty();
150 }
151 } 159 }
152 160
153 void _onResize(_) { 161 void _onResize(_) {
154 final newHeight = getBoundingClientRect().height; 162 final newHeight = getBoundingClientRect().height;
155 if (newHeight > _height) { 163 if (newHeight > _height) {
156 _height = newHeight; 164 _height = newHeight;
157 _r.dirty(); 165 _r.dirty();
158 } 166 }
159 } 167 }
160 } 168 }
OLDNEW
« no previous file with comments | « runtime/observatory/lib/src/elements/allocation_profile.dart ('k') | runtime/observatory/lib/src/elements/cpu_profile.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698