mirror of
https://github.com/flutter/flutter.git
synced 2025-06-03 00:51:18 +00:00

Similar to widgets.dart, rendering.dart exports the entire rendering layer. Also, update the examples to use rendering.dart and widgets.dart. Also clean up some exports so that the examples have more sensible imports.
179 lines
5.4 KiB
Dart
179 lines
5.4 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 'dart:sky' as sky;
|
|
|
|
import 'package:sky/base/lerp.dart';
|
|
import 'package:sky/rendering.dart';
|
|
import 'package:sky/theme/colors.dart' as colors;
|
|
import 'package:sky/widgets.dart';
|
|
|
|
class CardModel {
|
|
CardModel(this.value, this.height, this.color);
|
|
int value;
|
|
double height;
|
|
Color color;
|
|
String get label => "Card $value";
|
|
Key get key => new Key.fromObjectIdentity(this);
|
|
}
|
|
|
|
enum MarkerType { topLeft, bottomRight, touch }
|
|
|
|
class Marker extends Component {
|
|
Marker({
|
|
this.type: MarkerType.touch,
|
|
this.position,
|
|
this.size: 40.0,
|
|
Key key }) : super(key: key);
|
|
|
|
final Point position;
|
|
final double size;
|
|
final MarkerType type;
|
|
|
|
void paintMarker(sky.Canvas canvas, _) {
|
|
Paint paint = new Paint()..color = const Color(0x8000FF00);
|
|
paint.setStyle(sky.PaintingStyle.fill);
|
|
double r = size / 2.0;
|
|
canvas.drawCircle(new Point(r, r), r, paint);
|
|
|
|
paint.color = const Color(0xFFFFFFFF);
|
|
paint.setStyle(sky.PaintingStyle.stroke);
|
|
paint.strokeWidth = 1.0;
|
|
if (type == MarkerType.topLeft) {
|
|
canvas.drawLine(new Point(r, r), new Point(r + r - 1.0, r), paint);
|
|
canvas.drawLine(new Point(r, r), new Point(r, r + r - 1.0), paint);
|
|
}
|
|
if (type == MarkerType.bottomRight) {
|
|
canvas.drawLine(new Point(r, r), new Point(1.0, r), paint);
|
|
canvas.drawLine(new Point(r, r), new Point(r, 1.0), paint);
|
|
}
|
|
}
|
|
|
|
Widget build() {
|
|
return new Positioned(
|
|
left: position.x - size / 2.0,
|
|
top: position.y - size / 2.0,
|
|
child: new IgnorePointer(
|
|
child: new Container(
|
|
width: size,
|
|
height: size,
|
|
child: new CustomPaint(callback: paintMarker)
|
|
)
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
class OverlayGeometryApp extends App {
|
|
|
|
static const TextStyle cardLabelStyle =
|
|
const TextStyle(color: colors.white, fontSize: 18.0, fontWeight: bold);
|
|
|
|
List<CardModel> cardModels;
|
|
BlockViewportLayoutState layoutState = new BlockViewportLayoutState();
|
|
Map<MarkerType, Point> markers = new Map<MarkerType, Point>();
|
|
double markersScrollOffset;
|
|
ScrollListener scrollListener;
|
|
|
|
void initState() {
|
|
List<double> cardHeights = <double>[
|
|
48.0, 63.0, 82.0, 146.0, 60.0, 55.0, 84.0, 96.0, 50.0,
|
|
48.0, 63.0, 82.0, 146.0, 60.0, 55.0, 84.0, 96.0, 50.0,
|
|
48.0, 63.0, 82.0, 146.0, 60.0, 55.0, 84.0, 96.0, 50.0
|
|
];
|
|
cardModels = new List.generate(cardHeights.length, (i) {
|
|
Color color = lerpColor(colors.Red[300], colors.Blue[900], i / cardHeights.length);
|
|
return new CardModel(i, cardHeights[i], color);
|
|
});
|
|
super.initState();
|
|
}
|
|
|
|
void handleScroll(Scrollable scrollable) {
|
|
setState(() {
|
|
double dy = markersScrollOffset - scrollable.scrollOffset;
|
|
markersScrollOffset = scrollable.scrollOffset;
|
|
for (MarkerType type in markers.keys) {
|
|
Point oldPosition = markers[type];
|
|
markers[type] = new Point(oldPosition.x, oldPosition.y + dy);
|
|
}
|
|
});
|
|
}
|
|
|
|
EventDisposition handlePointerDown(Widget target, sky.PointerEvent event) {
|
|
setState(() {
|
|
markers[MarkerType.touch] = new Point(event.x, event.y);
|
|
markers[MarkerType.topLeft] = target.localToGlobal(new Point(0.0, 0.0));
|
|
Size size = (target.renderObject as RenderBox).size;
|
|
markers[MarkerType.bottomRight] = target.localToGlobal(new Point(size.width, size.height));
|
|
|
|
Scrollable scrollable = findScrollableAncestor(target: target);
|
|
markersScrollOffset = scrollable.scrollOffset;
|
|
if (scrollListener == null) {
|
|
scrollListener = () { handleScroll(scrollable); };
|
|
scrollable.addListener(scrollListener);
|
|
}
|
|
});
|
|
|
|
return EventDisposition.processed;
|
|
}
|
|
|
|
Widget builder(int index) {
|
|
if (index >= cardModels.length)
|
|
return null;
|
|
CardModel cardModel = cardModels[index];
|
|
Widget card = new Card(
|
|
color: cardModel.color,
|
|
child: new Container(
|
|
height: cardModel.height,
|
|
padding: const EdgeDims.all(8.0),
|
|
child: new Center(child: new Text(cardModel.label, style: cardLabelStyle))
|
|
)
|
|
);
|
|
return new Listener(
|
|
key: cardModel.key,
|
|
onPointerDown: (e) { return handlePointerDown(card, e); },
|
|
child: card
|
|
);
|
|
}
|
|
|
|
Widget build() {
|
|
Scrollable scrollable = new VariableHeightScrollable(
|
|
builder: builder,
|
|
token: cardModels.length,
|
|
layoutState: layoutState
|
|
);
|
|
|
|
Widget cardCollection = new Container(
|
|
padding: const EdgeDims.symmetric(vertical: 12.0, horizontal: 8.0),
|
|
decoration: new BoxDecoration(backgroundColor: Theme.of(this).primarySwatch[50]),
|
|
child: scrollable
|
|
);
|
|
|
|
List<Widget> layers = <Widget>[
|
|
new Scaffold(
|
|
toolbar: new ToolBar(center: new Text('Tap a Card')),
|
|
body: cardCollection
|
|
)
|
|
];
|
|
for (MarkerType type in markers.keys)
|
|
layers.add(new Marker(type: type, position: markers[type]));
|
|
|
|
return new IconTheme(
|
|
data: const IconThemeData(color: IconThemeColor.white),
|
|
child: new Theme(
|
|
data: new ThemeData(
|
|
brightness: ThemeBrightness.light,
|
|
primarySwatch: colors.Blue,
|
|
accentColor: colors.RedAccent[200]
|
|
),
|
|
child: new TaskDescription(label: 'Cards', child: new Stack(layers))
|
|
)
|
|
);
|
|
}
|
|
}
|
|
|
|
void main() {
|
|
runApp(new OverlayGeometryApp());
|
|
}
|