Add a proper material shadow the popup menu

R=eseidel@chromium.org

Review URL: https://codereview.chromium.org/1172723002.
This commit is contained in:
Adam Barth 2015-06-09 10:31:39 -07:00
parent ecb61e1466
commit 7a930b8352
4 changed files with 133 additions and 85 deletions

View File

@ -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
));
}

View File

@ -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)
)
);
}

View File

@ -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 {

View File

@ -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),
],
};