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

Factor out a reusable interface called Decoration from BoxDecoration. Make all the consumers of BoxDecoration and the erstwhile BoxPainter into consumers of Decoration. Make a BoxPainter be something you get from a Decoration, rather than something to which you pass a BoxDecoration. Rename Shape to BoxShape now that it's documented specifically as applying to boxes. Move EdgeDims to its own file. Move FractionalOffset up so that it's with the other helper classes in its file rather than alone at the end. Minor change to RenderClipOval's hit testing to avoid taking an unnecessary square root. Rename BoxDecorationPosition to DecorationPosition since RenderDecoratedBox now takes any Decoration. Implement hit testing for rounded rects. Rename AnimatedBoxDecorationValue to AnimatedDecorationValue, and make it support lerping across any Decoration (by deferring to the objects involved).
181 lines
4.7 KiB
Dart
181 lines
4.7 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 'package:flutter/material.dart';
|
|
import 'package:flutter/painting.dart';
|
|
import 'package:flutter/rendering.dart';
|
|
|
|
class ExampleDragTarget extends StatefulComponent {
|
|
ExampleDragTargetState createState() => new ExampleDragTargetState();
|
|
}
|
|
|
|
class ExampleDragTargetState extends State<ExampleDragTarget> {
|
|
Color _color = Colors.grey[500];
|
|
|
|
void _handleAccept(Color data) {
|
|
setState(() {
|
|
_color = data;
|
|
});
|
|
}
|
|
|
|
Widget build(BuildContext context) {
|
|
return new DragTarget<Color>(
|
|
onAccept: _handleAccept,
|
|
builder: (BuildContext context, List<Color> data, _) {
|
|
return new Container(
|
|
height: 100.0,
|
|
margin: new EdgeDims.all(10.0),
|
|
decoration: new BoxDecoration(
|
|
border: new Border.all(
|
|
width: 3.0,
|
|
color: data.isEmpty ? Colors.white : Colors.blue[500]
|
|
),
|
|
backgroundColor: data.isEmpty ? _color : Colors.grey[200]
|
|
)
|
|
);
|
|
}
|
|
);
|
|
}
|
|
}
|
|
|
|
class Dot extends StatelessComponent {
|
|
Dot({ Key key, this.color, this.size, this.child }) : super(key: key);
|
|
final Color color;
|
|
final double size;
|
|
final Widget child;
|
|
Widget build(BuildContext context) {
|
|
return new Container(
|
|
width: size,
|
|
height: size,
|
|
decoration: new BoxDecoration(
|
|
backgroundColor: color,
|
|
shape: BoxShape.circle
|
|
),
|
|
child: child
|
|
);
|
|
}
|
|
}
|
|
|
|
class ExampleDragSource extends StatelessComponent {
|
|
ExampleDragSource({
|
|
Key key,
|
|
this.color,
|
|
this.heavy: false,
|
|
this.under: true,
|
|
this.child
|
|
}) : super(key: key);
|
|
|
|
final Color color;
|
|
final bool heavy;
|
|
final bool under;
|
|
final Widget child;
|
|
|
|
static const double kDotSize = 50.0;
|
|
static const double kHeavyMultiplier = 1.5;
|
|
static const double kFingerSize = 50.0;
|
|
|
|
Widget build(BuildContext context) {
|
|
double size = kDotSize;
|
|
if (heavy)
|
|
size *= kHeavyMultiplier;
|
|
|
|
Widget contents = new DefaultTextStyle(
|
|
style: Theme.of(context).text.body1.copyWith(textAlign: TextAlign.center),
|
|
child: new Dot(
|
|
color: color,
|
|
size: size,
|
|
child: new Center(child: child)
|
|
)
|
|
);
|
|
|
|
Widget feedback = new Opacity(
|
|
opacity: 0.75,
|
|
child: contents
|
|
);
|
|
|
|
Offset feedbackOffset;
|
|
DragAnchor anchor;
|
|
if (!under) {
|
|
feedback = new Transform(
|
|
transform: new Matrix4.identity()
|
|
..translate(-size / 2.0, -(size / 2.0 + kFingerSize)),
|
|
child: feedback
|
|
);
|
|
feedbackOffset = const Offset(0.0, -kFingerSize);
|
|
anchor = DragAnchor.pointer;
|
|
} else {
|
|
feedbackOffset = Offset.zero;
|
|
anchor = DragAnchor.child;
|
|
}
|
|
|
|
if (heavy) {
|
|
return new LongPressDraggable<Color>(
|
|
data: color,
|
|
child: contents,
|
|
feedback: feedback,
|
|
feedbackOffset: feedbackOffset,
|
|
dragAnchor: anchor
|
|
);
|
|
} else {
|
|
return new Draggable<Color>(
|
|
data: color,
|
|
child: contents,
|
|
feedback: feedback,
|
|
feedbackOffset: feedbackOffset,
|
|
dragAnchor: anchor
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
class DragAndDropApp extends StatelessComponent {
|
|
Widget build(BuildContext context) {
|
|
return new Scaffold(
|
|
toolBar: new ToolBar(
|
|
center: new Text('Drag and Drop Flutter Demo')
|
|
),
|
|
body: new Column(<Widget>[
|
|
new Flexible(child: new Row(<Widget>[
|
|
new ExampleDragSource(
|
|
color: const Color(0xFFFFF000),
|
|
under: true,
|
|
heavy: false,
|
|
child: new Text('under')
|
|
),
|
|
new ExampleDragSource(
|
|
color: const Color(0xFF0FFF00),
|
|
under: false,
|
|
heavy: true,
|
|
child: new Text('long-press above')
|
|
),
|
|
new ExampleDragSource(
|
|
color: const Color(0xFF00FFF0),
|
|
under: false,
|
|
heavy: false,
|
|
child: new Text('above')
|
|
),
|
|
],
|
|
alignItems: FlexAlignItems.center,
|
|
justifyContent: FlexJustifyContent.spaceAround
|
|
)),
|
|
new Flexible(child: new Row(<Widget>[
|
|
new Flexible(child: new ExampleDragTarget()),
|
|
new Flexible(child: new ExampleDragTarget()),
|
|
new Flexible(child: new ExampleDragTarget()),
|
|
new Flexible(child: new ExampleDragTarget()),
|
|
])),
|
|
])
|
|
);
|
|
}
|
|
}
|
|
|
|
void main() {
|
|
runApp(new MaterialApp(
|
|
title: 'Drag and Drop Flutter Demo',
|
|
routes: <String, RouteBuilder>{
|
|
'/': (RouteArguments args) => new DragAndDropApp()
|
|
}
|
|
));
|
|
}
|