flutter_flutter/framework/components/fixed_height_scrollable.dart
Hixie e8ead8bbbe [Effen] Port fn.dart from the legacy sky.Node backend to the RenderNode backend, which is currently just a sky.Node-backed shim, but will eventually be the core Sky interface for layout and painting.
- the custom layout class in fn is removed by this patch; a new class
  will be added in a later CL

- the version of layout.dart in this CL is a subset of what we're
  targetting on the long run with
     https://codereview.chromium.org/1093633002

- a couple of lines of dead code are removed in this CL also

R=eseidel@chromium.org

Review URL: https://codereview.chromium.org/1117143003
2015-05-08 13:06:47 -07:00

107 lines
2.9 KiB
Dart

// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import '../animation/scroll_behavior.dart';
import '../debug/tracing.dart';
import '../fn.dart';
import 'dart:math' as math;
import 'dart:async';
import 'scrollable.dart';
abstract class FixedHeightScrollable extends Scrollable {
static final Style _style = new Style('''
overflow: hidden;
position: relative;
will-change: transform;'''
);
static final Style _scrollAreaStyle = new Style('''
position:relative;
will-change: transform;'''
);
FixedHeightScrollable({
Object key
}) : super(key: key);
ScrollBehavior createScrollBehavior() => new OverscrollBehavior();
OverscrollBehavior get scrollBehavior => super.scrollBehavior as OverscrollBehavior;
double _height = 0.0;
double _itemHeight;
int _itemCount = 0;
int get itemCount => _itemCount;
void set itemCount (int value) {
if (_itemCount != value) {
_itemCount = value;
if (_itemHeight != null)
scrollBehavior.contentsHeight = _itemHeight * _itemCount;
}
}
void _measureHeights() {
trace('FixedHeightScrollable::_measureHeights', () {
if (_itemHeight != null)
return;
var root = getRoot();
if (root == null)
return;
var item = root.firstChild.firstChild;
if (item == null)
return;
setState(() {
_height = root.height;
assert(_height > 0);
_itemHeight = item.height;
assert(_itemHeight > 0);
scrollBehavior.containerHeight = _height;
scrollBehavior.contentsHeight = _itemHeight * _itemCount;
});
});
}
UINode buildContent() {
var itemNumber = 0;
var drawCount = 1;
var transformStyle = '';
if (_itemHeight == null)
new Future.microtask(_measureHeights);
if (_height > 0.0 && _itemHeight != null) {
if (scrollOffset < 0.0) {
double visibleHeight = _height + scrollOffset;
drawCount = (visibleHeight / _itemHeight).round() + 1;
transformStyle =
'transform: translateY(${(-scrollOffset).toStringAsFixed(2)}px)';
} else {
drawCount = (_height / _itemHeight).round() + 1;
double alignmentDelta = -scrollOffset % _itemHeight;
if (alignmentDelta != 0.0)
alignmentDelta -= _itemHeight;
double drawStart = scrollOffset + alignmentDelta;
itemNumber = math.max(0, (drawStart / _itemHeight).floor());
transformStyle =
'transform: translateY(${(alignmentDelta).toStringAsFixed(2)}px)';
}
}
return new Container(
style: _style,
children: [
new Container(
style: _scrollAreaStyle,
inlineStyle: transformStyle,
children: buildItems(itemNumber, drawCount)
)
]
);
}
List<UINode> buildItems(int start, int count);
}