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

Side by Side Diff: sky/framework/components/fixed_height_scrollable.dart

Issue 1006533002: Factor a Scrollable base class out of FixedHeightScrollable (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 9 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
« no previous file with comments | « no previous file | sky/framework/components/scrollable.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 import '../animation/fling_curve.dart';
6 import '../fn.dart'; 5 import '../fn.dart';
7 import 'dart:sky' as sky; 6 import 'dart:sky' as sky;
7 import 'scrollable.dart';
8 8
9 abstract class FixedHeightScrollable extends Component { 9 abstract class FixedHeightScrollable extends Scrollable {
10 // TODO(rafaelw): This component really shouldn't have an opinion 10 // TODO(rafaelw): This component really shouldn't have an opinion
11 // about how it is sized. The owning component should decide whether 11 // about how it is sized. The owning component should decide whether
12 // it's explicitly sized or flexible or whatever... 12 // it's explicitly sized or flexible or whatever...
13 static final Style _style = new Style(''' 13 static final Style _style = new Style('''
14 overflow: hidden; 14 overflow: hidden;
15 position: relative; 15 position: relative;
16 flex: 1; 16 flex: 1;
17 will-change: transform;''' 17 will-change: transform;'''
18 ); 18 );
19 19
20 static final Style _scrollAreaStyle = new Style(''' 20 static final Style _scrollAreaStyle = new Style('''
21 position:relative; 21 position:relative;
22 will-change: transform;''' 22 will-change: transform;'''
23 ); 23 );
24 24
25 double minOffset;
26 double maxOffset;
27
28 double _scrollOffset = 0.0;
29 FlingCurve _flingCurve;
30 int _flingAnimationId;
31 double _height = 0.0; 25 double _height = 0.0;
32 double _itemHeight; 26 double _itemHeight;
33 27
34 FixedHeightScrollable({ 28 FixedHeightScrollable({
35 Object key, 29 Object key,
36 this.minOffset, 30 double minOffset,
37 this.maxOffset 31 double maxOffset
38 }) : super(key: key) { 32 }) : super(key: key, minOffset: minOffset, maxOffset: maxOffset) {
39 events.listen('gestureflingstart', _handleFlingStart);
40 events.listen('gestureflingcancel', _handleFlingCancel);
41 events.listen('gesturescrollupdate', _handleScrollUpdate);
42 events.listen('wheel', _handleWheel);
43 } 33 }
44 34
45 List<Node> buildItems(int start, int count);
46
47 void didMount() { 35 void didMount() {
36 super.didMount();
48 var root = getRoot(); 37 var root = getRoot();
49 var item = root.firstChild.firstChild; 38 var item = root.firstChild.firstChild;
50 sky.ClientRect scrollRect = root.getBoundingClientRect(); 39 sky.ClientRect scrollRect = root.getBoundingClientRect();
51 sky.ClientRect itemRect = item.getBoundingClientRect(); 40 sky.ClientRect itemRect = item.getBoundingClientRect();
52 assert(scrollRect.height > 0); 41 assert(scrollRect.height > 0);
53 assert(itemRect.height > 0); 42 assert(itemRect.height > 0);
54 43
55 setState(() { 44 setState(() {
56 _height = scrollRect.height; 45 _height = scrollRect.height;
57 _itemHeight = itemRect.height; 46 _itemHeight = itemRect.height;
58 }); 47 });
59 } 48 }
60 49
61 Node build() { 50 Node build() {
62 var itemNumber = 0; 51 var itemNumber = 0;
63 var drawCount = 1; 52 var drawCount = 1;
64 var transformStyle = ''; 53 var transformStyle = '';
65 54
66 if (_height > 0.0) { 55 if (_height > 0.0) {
67 drawCount = (_height / _itemHeight).round() + 1; 56 drawCount = (_height / _itemHeight).round() + 1;
68 double alignmentDelta = -_scrollOffset % _itemHeight; 57 double alignmentDelta = -scrollOffset % _itemHeight;
69 if (alignmentDelta != 0.0) { 58 if (alignmentDelta != 0.0) {
70 alignmentDelta -= _itemHeight; 59 alignmentDelta -= _itemHeight;
71 } 60 }
72 61
73 double drawStart = _scrollOffset + alignmentDelta; 62 double drawStart = scrollOffset + alignmentDelta;
74 itemNumber = (drawStart / _itemHeight).floor(); 63 itemNumber = (drawStart / _itemHeight).floor();
75 64
76 transformStyle = 65 transformStyle =
77 'transform: translateY(${(alignmentDelta).toStringAsFixed(2)}px)'; 66 'transform: translateY(${(alignmentDelta).toStringAsFixed(2)}px)';
78 } 67 }
79 68
80 return new Container( 69 return new Container(
81 styles: [_style], 70 styles: [_style],
82 children: [ 71 children: [
83 new Container( 72 new Container(
84 styles: [_scrollAreaStyle], 73 styles: [_scrollAreaStyle],
85 inlineStyle: transformStyle, 74 inlineStyle: transformStyle,
86 children: buildItems(itemNumber, drawCount) 75 children: buildItems(itemNumber, drawCount)
87 ) 76 )
88 ] 77 ]
89 ); 78 );
90 } 79 }
91
92 void didUnmount() {
93 _stopFling();
94 }
95
96 bool _scrollBy(double scrollDelta) {
97 var newScrollOffset = _scrollOffset + scrollDelta;
98 if (minOffset != null && newScrollOffset < minOffset) {
99 newScrollOffset = minOffset;
100 } else if (maxOffset != null && newScrollOffset > maxOffset) {
101 newScrollOffset = maxOffset;
102 }
103 if (newScrollOffset == _scrollOffset) {
104 return false;
105 }
106
107 setState(() {
108 _scrollOffset = newScrollOffset;
109 });
110 return true;
111 }
112
113 void _scheduleFlingUpdate() {
114 _flingAnimationId = sky.window.requestAnimationFrame(_updateFling);
115 }
116
117 void _stopFling() {
118 if (_flingAnimationId == null) {
119 return;
120 }
121
122 sky.window.cancelAnimationFrame(_flingAnimationId);
123 _flingCurve = null;
124 _flingAnimationId = null;
125 }
126
127 void _updateFling(double timeStamp) {
128 double scrollDelta = _flingCurve.update(timeStamp);
129 if (!_scrollBy(scrollDelta))
130 return _stopFling();
131 _scheduleFlingUpdate();
132 }
133
134 void _handleScrollUpdate(sky.GestureEvent event) {
135 _scrollBy(-event.dy);
136 }
137
138 void _handleFlingStart(sky.GestureEvent event) {
139 setState(() {
140 _flingCurve = new FlingCurve(-event.velocityY, event.timeStamp);
141 _scheduleFlingUpdate();
142 });
143 }
144
145 void _handleFlingCancel(sky.GestureEvent event) {
146 _stopFling();
147 }
148
149 void _handleWheel(sky.WheelEvent event) {
150 _scrollBy(-event.offsetY);
151 }
152 } 80 }
OLDNEW
« no previous file with comments | « no previous file | sky/framework/components/scrollable.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698