blob: 5eb8f72ef0476d51f4497ce96e0186c22800a6e8 [file] [log] [blame]
// 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 'dart:async';
import 'package:flutter/animation.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';
const double _kMinScrollbarThumbLength = 18.0;
const double _kScrollbarThumbGirth = 6.0;
const Duration _kScrollbarThumbFadeDuration = const Duration(milliseconds: 300);
class ScrollbarPainter extends ScrollableListPainter {
double _opacity = 0.0;
int get _alpha => (_opacity * 0xFF).round();
// TODO(hansmuller): thumb color should come from ThemeData.
Color get thumbColor => const Color(0xFF9E9E9E);
void paintThumb(PaintingContext context, Rect thumbBounds) {
final Paint paint = new Paint()..color = thumbColor.withAlpha(_alpha);
context.canvas.drawRect(thumbBounds, paint);
}
void paintScrollbar(PaintingContext context, Offset offset) {
final Rect viewportBounds = offset & viewportSize;
Point thumbOrigin;
Size thumbSize;
if (isVertical) {
double thumbHeight = viewportBounds.height * viewportBounds.height / contentExtent;
thumbHeight = thumbHeight.clamp(_kMinScrollbarThumbLength, viewportBounds.height);
final double maxThumbTop = viewportBounds.height - thumbHeight;
double thumbTop = (scrollOffset / (contentExtent - viewportBounds.height)) * maxThumbTop;
thumbTop = viewportBounds.top + thumbTop.clamp(0.0, maxThumbTop);
thumbOrigin = new Point(viewportBounds.right - _kScrollbarThumbGirth, thumbTop);
thumbSize = new Size(_kScrollbarThumbGirth, thumbHeight);
} else {
double thumbWidth = viewportBounds.width * viewportBounds.width / contentExtent;
thumbWidth = thumbWidth.clamp(_kMinScrollbarThumbLength, viewportBounds.width);
final double maxThumbLeft = viewportBounds.width - thumbWidth;
double thumbLeft = (scrollOffset / (contentExtent - viewportBounds.width)) * maxThumbLeft;
thumbLeft = viewportBounds.left + thumbLeft.clamp(0.0, maxThumbLeft);
thumbOrigin = new Point(thumbLeft, viewportBounds.height - _kScrollbarThumbGirth);
thumbSize = new Size(thumbWidth, _kScrollbarThumbGirth);
}
paintThumb(context, thumbOrigin & thumbSize);
}
void paint(PaintingContext context, Offset offset) {
if (_alpha == 0)
return;
paintScrollbar(context, offset);
}
ValuePerformance<double> _fade;
Future scrollStarted() {
_fade ??= new ValuePerformance<double>()
..duration = _kScrollbarThumbFadeDuration
..variable = new AnimatedValue<double>(0.0, end: 1.0, curve: Curves.ease)
..addListener(() {
_opacity = _fade.value;
renderer?.markNeedsPaint();
});
return _fade.forward();
}
Future scrollEnded() {
return _fade.reverse();
}
void detach() {
super.detach();
_fade?.stop();
}
}