mirror of https://github.com/flutter/samples.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
184 lines
4.9 KiB
184 lines
4.9 KiB
// Copyright 2018 the Charts project authors. Please see the AUTHORS file
|
|
// for details.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
import 'package:flutter_web_ui/ui.dart' show TextAlign, TextDirection;
|
|
import 'package:charts_common/common.dart' as common
|
|
show
|
|
MaxWidthStrategy,
|
|
TextElement,
|
|
TextDirection,
|
|
TextMeasurement,
|
|
TextStyle;
|
|
import 'package:flutter_web/rendering.dart'
|
|
show Color, TextBaseline, TextPainter, TextSpan, TextStyle;
|
|
|
|
/// Flutter implementation for text measurement and painter.
|
|
class TextElement implements common.TextElement {
|
|
static const ellipsis = '\u{2026}';
|
|
|
|
@override
|
|
final String text;
|
|
|
|
final double textScaleFactor;
|
|
|
|
var _painterReady = false;
|
|
common.TextStyle _textStyle;
|
|
common.TextDirection _textDirection = common.TextDirection.ltr;
|
|
|
|
int _maxWidth;
|
|
common.MaxWidthStrategy _maxWidthStrategy;
|
|
|
|
TextPainter _textPainter;
|
|
|
|
common.TextMeasurement _measurement;
|
|
|
|
double _opacity;
|
|
|
|
TextElement(this.text, {common.TextStyle style, this.textScaleFactor})
|
|
: _textStyle = style;
|
|
|
|
@override
|
|
common.TextStyle get textStyle => _textStyle;
|
|
|
|
@override
|
|
set textStyle(common.TextStyle value) {
|
|
if (_textStyle == value) {
|
|
return;
|
|
}
|
|
_textStyle = value;
|
|
_painterReady = false;
|
|
}
|
|
|
|
@override
|
|
set textDirection(common.TextDirection direction) {
|
|
if (_textDirection == direction) {
|
|
return;
|
|
}
|
|
_textDirection = direction;
|
|
_painterReady = false;
|
|
}
|
|
|
|
@override
|
|
common.TextDirection get textDirection => _textDirection;
|
|
|
|
@override
|
|
int get maxWidth => _maxWidth;
|
|
|
|
@override
|
|
set maxWidth(int value) {
|
|
if (_maxWidth == value) {
|
|
return;
|
|
}
|
|
_maxWidth = value;
|
|
_painterReady = false;
|
|
}
|
|
|
|
@override
|
|
common.MaxWidthStrategy get maxWidthStrategy => _maxWidthStrategy;
|
|
|
|
@override
|
|
set maxWidthStrategy(common.MaxWidthStrategy maxWidthStrategy) {
|
|
if (_maxWidthStrategy == maxWidthStrategy) {
|
|
return;
|
|
}
|
|
_maxWidthStrategy = maxWidthStrategy;
|
|
_painterReady = false;
|
|
}
|
|
|
|
@override
|
|
set opacity(double opacity) {
|
|
if (opacity != _opacity) {
|
|
_painterReady = false;
|
|
_opacity = opacity;
|
|
}
|
|
}
|
|
|
|
@override
|
|
common.TextMeasurement get measurement {
|
|
if (!_painterReady) {
|
|
_refreshPainter();
|
|
}
|
|
|
|
return _measurement;
|
|
}
|
|
|
|
/// The estimated distance between where we asked to draw the text (top, left)
|
|
/// and where it visually started (top + verticalFontShift, left).
|
|
///
|
|
/// 10% of reported font height seems to be about right.
|
|
int get verticalFontShift {
|
|
if (!_painterReady) {
|
|
_refreshPainter();
|
|
}
|
|
|
|
return (_textPainter.height * 0.1).ceil();
|
|
}
|
|
|
|
TextPainter get textPainter {
|
|
if (!_painterReady) {
|
|
_refreshPainter();
|
|
}
|
|
return _textPainter;
|
|
}
|
|
|
|
/// Create text painter and measure based on current settings
|
|
void _refreshPainter() {
|
|
_opacity ??= 1.0;
|
|
var color = new Color.fromARGB(
|
|
(textStyle.color.a * _opacity).round(),
|
|
textStyle.color.r,
|
|
textStyle.color.g,
|
|
textStyle.color.b,
|
|
);
|
|
|
|
_textPainter = new TextPainter(
|
|
text: new TextSpan(
|
|
text: text,
|
|
style: new TextStyle(
|
|
color: color,
|
|
fontSize: textStyle.fontSize.toDouble(),
|
|
fontFamily: textStyle.fontFamily)))
|
|
..textDirection = TextDirection.ltr
|
|
// TODO Flip once textAlign works
|
|
..textAlign = TextAlign.left
|
|
// ..textAlign = _textDirection == common.TextDirection.rtl ?
|
|
// TextAlign.right : TextAlign.left
|
|
..ellipsis = maxWidthStrategy == common.MaxWidthStrategy.ellipsize
|
|
? ellipsis
|
|
: null;
|
|
|
|
if (textScaleFactor != null) {
|
|
_textPainter.textScaleFactor = textScaleFactor;
|
|
}
|
|
|
|
_textPainter.layout(maxWidth: maxWidth?.toDouble() ?? double.infinity);
|
|
|
|
final baseline =
|
|
_textPainter.computeDistanceToActualBaseline(TextBaseline.alphabetic);
|
|
|
|
// Estimating the actual draw height to 70% of measures size.
|
|
//
|
|
// The font reports a size larger than the drawn size, which makes it
|
|
// difficult to shift the text around to get it to visually line up
|
|
// vertically with other components.
|
|
_measurement = new common.TextMeasurement(
|
|
horizontalSliceWidth: _textPainter.width,
|
|
verticalSliceWidth: _textPainter.height * 0.70,
|
|
baseline: baseline);
|
|
|
|
_painterReady = true;
|
|
}
|
|
}
|