mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Add a proper material shadow the popup menu
R=eseidel@chromium.org Review URL: https://codereview.chromium.org/1172723002.
This commit is contained in:
parent
ecb61e1466
commit
7a930b8352
@ -6,17 +6,23 @@ import 'dart:sky';
|
||||
import 'package:sky/framework/app.dart';
|
||||
import 'package:sky/framework/rendering/box.dart';
|
||||
import 'package:sky/framework/rendering/flex.dart';
|
||||
import 'package:sky/framework/theme2/shadows.dart';
|
||||
|
||||
AppView app;
|
||||
|
||||
void main() {
|
||||
var coloredBox = new RenderDecoratedBox(
|
||||
decoration: new BoxDecoration(backgroundColor: const Color(0xFFFFFF00))
|
||||
decoration: new BoxDecoration(
|
||||
backgroundColor: const Color(0xFFFAFAFA),
|
||||
boxShadow: Shadow[3])
|
||||
);
|
||||
var shadow = const BoxShadow(
|
||||
color: const Color(0xFFEEEEEE), offset: const Size(5.0, 5.0), blur: 5.0);
|
||||
var shadowBox = new RenderShadowedBox(shadow: shadow, child: coloredBox);
|
||||
var paddedBox = new RenderPadding(padding: const EdgeDims.all(30.0),
|
||||
child: shadowBox);
|
||||
app = new AppView(paddedBox);
|
||||
var paddedBox = new RenderPadding(
|
||||
padding: const EdgeDims.all(50.0),
|
||||
child: coloredBox);
|
||||
app = new AppView(new RenderDecoratedBox(
|
||||
decoration: const BoxDecoration(
|
||||
backgroundColor: const Color(0xFFFFFFFF)
|
||||
),
|
||||
child: paddedBox
|
||||
));
|
||||
}
|
||||
|
||||
@ -2,10 +2,11 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
import 'animated_component.dart';
|
||||
import '../animation/animated_value.dart';
|
||||
import '../fn2.dart';
|
||||
import '../theme2/colors.dart';
|
||||
import '../theme2/shadows.dart';
|
||||
import 'animated_component.dart';
|
||||
import 'dart:async';
|
||||
import 'dart:math' as math;
|
||||
import 'material.dart';
|
||||
@ -98,16 +99,15 @@ class PopupMenu extends AnimatedComponent {
|
||||
return new PopupMenuItem(key: i++, children: item, opacity: opacity);
|
||||
}));
|
||||
|
||||
// border-radius: 2px
|
||||
// inlineStyle: _inlineStyle(),
|
||||
return new ShrinkWrapWidth(
|
||||
child: new Material(
|
||||
content: new Container(
|
||||
padding: const EdgeDims.all(8.0),
|
||||
// border-radius: 2px
|
||||
decoration: new BoxDecoration(backgroundColor: Grey[50]),
|
||||
// inlineStyle: _inlineStyle(),
|
||||
child: new BlockContainer(children: children)
|
||||
),
|
||||
level: level
|
||||
child: new Container(
|
||||
padding: const EdgeDims.all(8.0),
|
||||
decoration: new BoxDecoration(
|
||||
backgroundColor: Grey[50],
|
||||
boxShadow: Shadow[level]),
|
||||
child: new BlockContainer(children: children)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@ -630,15 +630,31 @@ class Border {
|
||||
String toString() => 'Border($top, $right, $bottom, $left)';
|
||||
}
|
||||
|
||||
class BoxShadow {
|
||||
const BoxShadow({
|
||||
this.color,
|
||||
this.offset,
|
||||
this.blur
|
||||
});
|
||||
|
||||
final Color color;
|
||||
final Size offset;
|
||||
final double blur;
|
||||
|
||||
String toString() => 'BoxShadow($color, $offset, $blur)';
|
||||
}
|
||||
|
||||
// This must be immutable, because we won't notice when it changes
|
||||
class BoxDecoration {
|
||||
const BoxDecoration({
|
||||
this.backgroundColor,
|
||||
this.border
|
||||
this.border,
|
||||
this.boxShadow
|
||||
});
|
||||
|
||||
final Color backgroundColor;
|
||||
final Border border;
|
||||
final List<BoxShadow> boxShadow;
|
||||
|
||||
String toString([String prefix = '']) {
|
||||
List<String> result = [];
|
||||
@ -646,6 +662,8 @@ class BoxDecoration {
|
||||
result.add('${prefix}backgroundColor: $backgroundColor');
|
||||
if (border != null)
|
||||
result.add('${prefix}border: $border');
|
||||
// if (boxShadow != null)
|
||||
// result.add('${prefix}boxShadow: $boxShadow');
|
||||
if (result.isEmpty)
|
||||
return '${prefix}<no decorations specified>';
|
||||
return result.join('\n');
|
||||
@ -668,17 +686,50 @@ class RenderDecoratedBox extends RenderProxyBox {
|
||||
if (value == _decoration)
|
||||
return;
|
||||
_decoration = value;
|
||||
_cachedBackgroundPaint = null;
|
||||
markNeedsPaint();
|
||||
}
|
||||
|
||||
Paint _cachedBackgroundPaint;
|
||||
Paint get _backgroundPaint {
|
||||
if (_cachedBackgroundPaint == null) {
|
||||
Paint paint = new Paint();
|
||||
|
||||
if (_decoration.backgroundColor != null)
|
||||
paint.color = _decoration.backgroundColor;
|
||||
|
||||
if (_decoration.boxShadow != null) {
|
||||
var builder = new sky.LayerDrawLooperBuilder();
|
||||
for (BoxShadow boxShadow in _decoration.boxShadow) {
|
||||
builder.addLayerOnTop(
|
||||
new sky.DrawLooperLayerInfo()
|
||||
..setPaintBits(-1)
|
||||
..setOffset(boxShadow.offset.toPoint())
|
||||
..setColorMode(sky.TransferMode.srcMode),
|
||||
(Paint layerPaint) {
|
||||
layerPaint.color = boxShadow.color;
|
||||
layerPaint.setMaskFilter(
|
||||
new sky.MaskFilter.Blur(sky.BlurStyle.normal,
|
||||
boxShadow.blur,
|
||||
highQuality: true));
|
||||
});
|
||||
}
|
||||
builder.addLayerOnTop(new sky.DrawLooperLayerInfo(), (_) {});
|
||||
paint.setDrawLooper(builder.build());
|
||||
}
|
||||
|
||||
_cachedBackgroundPaint = paint;
|
||||
}
|
||||
|
||||
return _cachedBackgroundPaint;
|
||||
}
|
||||
|
||||
void paint(RenderObjectDisplayList canvas) {
|
||||
assert(size.width != null);
|
||||
assert(size.height != null);
|
||||
|
||||
if (_decoration.backgroundColor != null) {
|
||||
Paint paint = new Paint()..color = _decoration.backgroundColor;
|
||||
canvas.drawRect(new Rect.fromLTRB(0.0, 0.0, size.width, size.height), paint);
|
||||
}
|
||||
if (_decoration.backgroundColor != null || _decoration.boxShadow != null)
|
||||
canvas.drawRect(new Rect.fromLTRB(0.0, 0.0, size.width, size.height), _backgroundPaint);
|
||||
|
||||
if (_decoration.border != null) {
|
||||
assert(_decoration.border.top != null);
|
||||
@ -823,63 +874,6 @@ class RenderSizeObserver extends RenderProxyBox {
|
||||
}
|
||||
}
|
||||
|
||||
// This must be immutable, because we won't notice when it changes
|
||||
class BoxShadow {
|
||||
const BoxShadow({
|
||||
this.color,
|
||||
this.offset,
|
||||
this.blur
|
||||
});
|
||||
|
||||
final Size offset;
|
||||
final double blur;
|
||||
final Color color;
|
||||
}
|
||||
|
||||
class RenderShadowedBox extends RenderProxyBox {
|
||||
|
||||
RenderShadowedBox({
|
||||
BoxShadow shadow,
|
||||
RenderBox child
|
||||
}) : _shadow = shadow, super(child);
|
||||
|
||||
BoxShadow _shadow;
|
||||
BoxShadow get shadow => _shadow;
|
||||
void set shadow (BoxShadow value) {
|
||||
if (value == _shadow)
|
||||
return;
|
||||
_shadow = value;
|
||||
markNeedsPaint();
|
||||
}
|
||||
|
||||
Paint _createShadowPaint(BoxShadow shadow) {
|
||||
// TODO(eseidel): This should not be hard-coded yellow.
|
||||
Paint paint = new Paint()..color = const Color.fromARGB(255, 0, 255, 0);
|
||||
var builder = new sky.LayerDrawLooperBuilder()
|
||||
// Shadow layer.
|
||||
..addLayerOnTop(
|
||||
new sky.DrawLooperLayerInfo()
|
||||
..setPaintBits(-1)
|
||||
..setOffset(shadow.offset.toPoint())
|
||||
..setColorMode(sky.TransferMode.srcMode),
|
||||
(Paint layerPaint) {
|
||||
layerPaint.color = shadow.color;
|
||||
layerPaint.setMaskFilter(
|
||||
new sky.MaskFilter.Blur(sky.BlurStyle.normal, shadow.blur, highQuality: true));
|
||||
})
|
||||
// Main layer.
|
||||
..addLayerOnTop(new sky.DrawLooperLayerInfo(), (_) {});
|
||||
paint.setDrawLooper(builder.build());
|
||||
return paint;
|
||||
}
|
||||
|
||||
void paint(RenderObjectDisplayList canvas) {
|
||||
Paint paint = _createShadowPaint(_shadow);
|
||||
canvas.drawRect(new Rect.fromLTRB(0.0, 0.0, size.width, size.height), paint);
|
||||
super.paint(canvas);
|
||||
}
|
||||
}
|
||||
|
||||
typedef void CustomPaintCallback(sky.Canvas canvas);
|
||||
|
||||
class RenderCustomPaint extends RenderProxyBox {
|
||||
|
||||
@ -2,10 +2,58 @@
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
const Map<int, String> Shadow = const {
|
||||
1: '0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24)',
|
||||
2: '0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23)',
|
||||
3: '0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23)',
|
||||
4: '0 14px 28px rgba(0,0,0,0.25), 0 10px 10px rgba(0,0,0,0.22)',
|
||||
5: '0 19px 38px rgba(0,0,0,0.30), 0 15px 12px rgba(0,0,0,0.22)',
|
||||
import '../rendering/box.dart';
|
||||
import 'dart:sky' show Color, Size;
|
||||
|
||||
const Map<int, List<BoxShadow>> Shadow = const {
|
||||
1: const [
|
||||
const BoxShadow(
|
||||
color: const Color(0x1F000000),
|
||||
offset: const Size(0.0, 1.0),
|
||||
blur: 3.0),
|
||||
const BoxShadow(
|
||||
color: const Color(0x3D000000),
|
||||
offset: const Size(0.0, 1.0),
|
||||
blur: 2.0),
|
||||
],
|
||||
2: const [
|
||||
const BoxShadow(
|
||||
color: const Color(0x29000000),
|
||||
offset: const Size(0.0, 3.0),
|
||||
blur: 6.0),
|
||||
const BoxShadow(
|
||||
color: const Color(0x3B000000),
|
||||
offset: const Size(0.0, 3.0),
|
||||
blur: 6.0),
|
||||
],
|
||||
3: const [
|
||||
const BoxShadow(
|
||||
color: const Color(0x30000000),
|
||||
offset: const Size(0.0, 10.0),
|
||||
blur: 20.0),
|
||||
const BoxShadow(
|
||||
color: const Color(0x3B000000),
|
||||
offset: const Size(0.0, 6.0),
|
||||
blur: 6.0),
|
||||
],
|
||||
4: const [
|
||||
const BoxShadow(
|
||||
color: const Color(0x40000000),
|
||||
offset: const Size(0.0, 14.0),
|
||||
blur: 28.0),
|
||||
const BoxShadow(
|
||||
color: const Color(0x38000000),
|
||||
offset: const Size(0.0, 10.0),
|
||||
blur: 10.0),
|
||||
],
|
||||
5: const [
|
||||
const BoxShadow(
|
||||
color: const Color(0x4E000000),
|
||||
offset: const Size(0.0, 19.0),
|
||||
blur: 28.0),
|
||||
const BoxShadow(
|
||||
color: const Color(0x38000000),
|
||||
offset: const Size(0.0, 15.0),
|
||||
blur: 12.0),
|
||||
],
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user