| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 import 'dart:math' as math; | 5 import 'dart:math' as math; |
| 6 import 'dart:sky' as sky; | 6 import 'dart:sky' as sky; |
| 7 import 'dart:typed_data'; | 7 import 'dart:typed_data'; |
| 8 import 'object.dart'; | 8 import 'object.dart'; |
| 9 import '../painting/shadows.dart'; | 9 import '../painting/box_painter.dart'; |
| 10 import 'package:vector_math/vector_math.dart'; | 10 import 'package:vector_math/vector_math.dart'; |
| 11 import 'package:sky/framework/net/image_cache.dart' as image_cache; | 11 import 'package:sky/framework/net/image_cache.dart' as image_cache; |
| 12 | 12 |
| 13 export '../painting/box_painter.dart'; |
| 14 |
| 13 // GENERIC BOX RENDERING | 15 // GENERIC BOX RENDERING |
| 14 // Anything that has a concept of x, y, width, height is going to derive from th
is | 16 // Anything that has a concept of x, y, width, height is going to derive from th
is |
| 15 | 17 |
| 16 class EdgeDims { | 18 class EdgeDims { |
| 17 // used for e.g. padding | 19 // used for e.g. padding |
| 18 const EdgeDims(this.top, this.right, this.bottom, this.left); | 20 const EdgeDims(this.top, this.right, this.bottom, this.left); |
| 19 const EdgeDims.all(double value) | 21 const EdgeDims.all(double value) |
| 20 : top = value, right = value, bottom = value, left = value; | 22 : top = value, right = value, bottom = value, left = value; |
| 21 const EdgeDims.only({ this.top: 0.0, | 23 const EdgeDims.only({ this.top: 0.0, |
| 22 this.right: 0.0, | 24 this.right: 0.0, |
| (...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 679 } | 681 } |
| 680 Paint paint = new Paint(); | 682 Paint paint = new Paint(); |
| 681 canvas.drawImage(_image, 0.0, 0.0, paint); | 683 canvas.drawImage(_image, 0.0, 0.0, paint); |
| 682 if (needsScale) | 684 if (needsScale) |
| 683 canvas.restore(); | 685 canvas.restore(); |
| 684 } | 686 } |
| 685 | 687 |
| 686 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(
prefix)}${prefix}url: ${src}\n${prefix}dimensions: ${requestedSize}\n'; | 688 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(
prefix)}${prefix}url: ${src}\n${prefix}dimensions: ${requestedSize}\n'; |
| 687 } | 689 } |
| 688 | 690 |
| 689 class BorderSide { | |
| 690 const BorderSide({ | |
| 691 this.color: const Color(0xFF000000), | |
| 692 this.width: 1.0 | |
| 693 }); | |
| 694 final Color color; | |
| 695 final double width; | |
| 696 | |
| 697 static const none = const BorderSide(width: 0.0); | |
| 698 | |
| 699 int get hashCode { | |
| 700 int value = 373; | |
| 701 value = 37 * value * color.hashCode; | |
| 702 value = 37 * value * width.hashCode; | |
| 703 return value; | |
| 704 } | |
| 705 String toString() => 'BorderSide($color, $width)'; | |
| 706 } | |
| 707 | |
| 708 class Border { | |
| 709 const Border({ | |
| 710 this.top: BorderSide.none, | |
| 711 this.right: BorderSide.none, | |
| 712 this.bottom: BorderSide.none, | |
| 713 this.left: BorderSide.none | |
| 714 }); | |
| 715 | |
| 716 const Border.all(BorderSide side) : | |
| 717 top = side, | |
| 718 right = side, | |
| 719 bottom = side, | |
| 720 left = side; | |
| 721 | |
| 722 final BorderSide top; | |
| 723 final BorderSide right; | |
| 724 final BorderSide bottom; | |
| 725 final BorderSide left; | |
| 726 | |
| 727 int get hashCode { | |
| 728 int value = 373; | |
| 729 value = 37 * value * top.hashCode; | |
| 730 value = 37 * value * right.hashCode; | |
| 731 value = 37 * value * bottom.hashCode; | |
| 732 value = 37 * value * left.hashCode; | |
| 733 return value; | |
| 734 } | |
| 735 String toString() => 'Border($top, $right, $bottom, $left)'; | |
| 736 } | |
| 737 | |
| 738 class BoxShadow { | |
| 739 const BoxShadow({ | |
| 740 this.color, | |
| 741 this.offset, | |
| 742 this.blur | |
| 743 }); | |
| 744 | |
| 745 final Color color; | |
| 746 final Size offset; | |
| 747 final double blur; | |
| 748 | |
| 749 String toString() => 'BoxShadow($color, $offset, $blur)'; | |
| 750 } | |
| 751 | |
| 752 abstract class Gradient { | |
| 753 sky.Shader createShader(); | |
| 754 } | |
| 755 | |
| 756 class LinearGradient extends Gradient { | |
| 757 LinearGradient({ | |
| 758 this.endPoints, | |
| 759 this.colors, | |
| 760 this.colorStops, | |
| 761 this.tileMode: sky.TileMode.clamp | |
| 762 }); | |
| 763 | |
| 764 String toString() => | |
| 765 'LinearGradient($endPoints, $colors, $colorStops, $tileMode)'; | |
| 766 | |
| 767 sky.Shader createShader() { | |
| 768 return new sky.Gradient.Linear(this.endPoints, this.colors, this.colorStops, | |
| 769 this.tileMode); | |
| 770 } | |
| 771 | |
| 772 final List<Point> endPoints; | |
| 773 final List<Color> colors; | |
| 774 final List<double> colorStops; | |
| 775 final sky.TileMode tileMode; | |
| 776 } | |
| 777 | |
| 778 class RadialGradient extends Gradient { | |
| 779 RadialGradient({ | |
| 780 this.center, | |
| 781 this.radius, | |
| 782 this.colors, | |
| 783 this.colorStops, | |
| 784 this.tileMode: sky.TileMode.clamp | |
| 785 }); | |
| 786 | |
| 787 String toString() => | |
| 788 'RadialGradient($center, $radius, $colors, $colorStops, $tileMode)'; | |
| 789 | |
| 790 sky.Shader createShader() { | |
| 791 return new sky.Gradient.Radial(this.center, this.radius, this.colors, | |
| 792 this.colorStops, this.tileMode); | |
| 793 } | |
| 794 | |
| 795 final Point center; | |
| 796 final double radius; | |
| 797 final List<Color> colors; | |
| 798 final List<double> colorStops; | |
| 799 final sky.TileMode tileMode; | |
| 800 } | |
| 801 | |
| 802 // This must be immutable, because we won't notice when it changes | |
| 803 class BoxDecoration { | |
| 804 const BoxDecoration({ | |
| 805 this.backgroundColor, | |
| 806 this.border, | |
| 807 this.borderRadius, | |
| 808 this.boxShadow, | |
| 809 this.gradient | |
| 810 }); | |
| 811 | |
| 812 final Color backgroundColor; | |
| 813 final double borderRadius; | |
| 814 final Border border; | |
| 815 final List<BoxShadow> boxShadow; | |
| 816 final Gradient gradient; | |
| 817 | |
| 818 String toString([String prefix = '']) { | |
| 819 List<String> result = []; | |
| 820 if (backgroundColor != null) | |
| 821 result.add('${prefix}backgroundColor: $backgroundColor'); | |
| 822 if (border != null) | |
| 823 result.add('${prefix}border: $border'); | |
| 824 if (borderRadius != null) | |
| 825 result.add('${prefix}borderRadius: $borderRadius'); | |
| 826 if (boxShadow != null) | |
| 827 result.add('${prefix}boxShadow: ${boxShadow.map((shadow) => shadow.toStrin
g())}'); | |
| 828 if (gradient != null) | |
| 829 result.add('${prefix}gradient: $gradient'); | |
| 830 if (result.isEmpty) | |
| 831 return '${prefix}<no decorations specified>'; | |
| 832 return result.join('\n'); | |
| 833 } | |
| 834 } | |
| 835 | |
| 836 class RenderDecoratedBox extends RenderProxyBox { | 691 class RenderDecoratedBox extends RenderProxyBox { |
| 837 | 692 |
| 838 RenderDecoratedBox({ | 693 RenderDecoratedBox({ |
| 839 BoxDecoration decoration, | 694 BoxDecoration decoration, |
| 840 RenderBox child | 695 RenderBox child |
| 841 }) : _decoration = decoration, super(child) { | 696 }) : _painter = new BoxPainter(decoration), super(child); |
| 842 assert(_decoration != null); | |
| 843 } | |
| 844 | 697 |
| 845 BoxDecoration _decoration; | 698 BoxPainter _painter; |
| 846 BoxDecoration get decoration => _decoration; | 699 BoxDecoration get decoration => _painter.decoration; |
| 847 void set decoration (BoxDecoration value) { | 700 void set decoration (BoxDecoration value) { |
| 848 assert(value != null); | 701 assert(value != null); |
| 849 if (value == _decoration) | 702 if (value == _painter.decoration) |
| 850 return; | 703 return; |
| 851 _decoration = value; | 704 _painter.decoration = value; |
| 852 _cachedBackgroundPaint = null; | |
| 853 markNeedsPaint(); | 705 markNeedsPaint(); |
| 854 } | 706 } |
| 855 | 707 |
| 856 Paint _cachedBackgroundPaint; | |
| 857 Paint get _backgroundPaint { | |
| 858 if (_cachedBackgroundPaint == null) { | |
| 859 Paint paint = new Paint(); | |
| 860 | |
| 861 if (_decoration.backgroundColor != null) | |
| 862 paint.color = _decoration.backgroundColor; | |
| 863 | |
| 864 if (_decoration.boxShadow != null) { | |
| 865 var builder = new ShadowDrawLooperBuilder(); | |
| 866 for (BoxShadow boxShadow in _decoration.boxShadow) | |
| 867 builder.addShadow(boxShadow.offset, boxShadow.color, boxShadow.blur); | |
| 868 paint.setDrawLooper(builder.build()); | |
| 869 } | |
| 870 | |
| 871 if (_decoration.gradient != null) | |
| 872 paint.setShader(_decoration.gradient.createShader()); | |
| 873 | |
| 874 _cachedBackgroundPaint = paint; | |
| 875 } | |
| 876 | |
| 877 return _cachedBackgroundPaint; | |
| 878 } | |
| 879 | |
| 880 void paint(RenderObjectDisplayList canvas) { | 708 void paint(RenderObjectDisplayList canvas) { |
| 881 assert(size.width != null); | 709 assert(size.width != null); |
| 882 assert(size.height != null); | 710 assert(size.height != null); |
| 883 | 711 _painter.paint(canvas, new Rect.fromSize(size)); |
| 884 if (_decoration.backgroundColor != null || _decoration.boxShadow != null || | |
| 885 _decoration.gradient != null) { | |
| 886 Rect rect = new Rect.fromLTRB(0.0, 0.0, size.width, size.height); | |
| 887 if (_decoration.borderRadius == null) | |
| 888 canvas.drawRect(rect, _backgroundPaint); | |
| 889 else | |
| 890 canvas.drawRRect(new sky.RRect()..setRectXY(rect, _decoration.borderRadi
us, _decoration.borderRadius), _backgroundPaint); | |
| 891 } | |
| 892 | |
| 893 if (_decoration.border != null) { | |
| 894 assert(_decoration.borderRadius == null); // TODO(abarth): Implement borde
rs with border radius. | |
| 895 | |
| 896 assert(_decoration.border.top != null); | |
| 897 assert(_decoration.border.right != null); | |
| 898 assert(_decoration.border.bottom != null); | |
| 899 assert(_decoration.border.left != null); | |
| 900 | |
| 901 Paint paint = new Paint(); | |
| 902 Path path; | |
| 903 | |
| 904 paint.color = _decoration.border.top.color; | |
| 905 path = new Path(); | |
| 906 path.moveTo(0.0,0.0); | |
| 907 path.lineTo(_decoration.border.left.width, _decoration.border.top.width); | |
| 908 path.lineTo(size.width - _decoration.border.right.width, _decoration.borde
r.top.width); | |
| 909 path.lineTo(size.width, 0.0); | |
| 910 path.close(); | |
| 911 canvas.drawPath(path, paint); | |
| 912 | |
| 913 paint.color = _decoration.border.right.color; | |
| 914 path = new Path(); | |
| 915 path.moveTo(size.width, 0.0); | |
| 916 path.lineTo(size.width - _decoration.border.right.width, _decoration.borde
r.top.width); | |
| 917 path.lineTo(size.width - _decoration.border.right.width, size.height - _de
coration.border.bottom.width); | |
| 918 path.lineTo(size.width, size.height); | |
| 919 path.close(); | |
| 920 canvas.drawPath(path, paint); | |
| 921 | |
| 922 paint.color = _decoration.border.bottom.color; | |
| 923 path = new Path(); | |
| 924 path.moveTo(size.width, size.height); | |
| 925 path.lineTo(size.width - _decoration.border.right.width, size.height - _de
coration.border.bottom.width); | |
| 926 path.lineTo(_decoration.border.left.width, size.height - _decoration.borde
r.bottom.width); | |
| 927 path.lineTo(0.0, size.height); | |
| 928 path.close(); | |
| 929 canvas.drawPath(path, paint); | |
| 930 | |
| 931 paint.color = _decoration.border.left.color; | |
| 932 path = new Path(); | |
| 933 path.moveTo(0.0, size.height); | |
| 934 path.lineTo(_decoration.border.left.width, size.height - _decoration.borde
r.bottom.width); | |
| 935 path.lineTo(_decoration.border.left.width, _decoration.border.top.width); | |
| 936 path.lineTo(0.0,0.0); | |
| 937 path.close(); | |
| 938 canvas.drawPath(path, paint); | |
| 939 } | |
| 940 | |
| 941 super.paint(canvas); | 712 super.paint(canvas); |
| 942 } | 713 } |
| 943 | 714 |
| 944 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(
prefix)}${prefix}decoration:\n${decoration.toString(prefix + " ")}\n'; | 715 String debugDescribeSettings(String prefix) => '${super.debugDescribeSettings(
prefix)}${prefix}decoration:\n${_painter.decoration.toString(prefix + " ")}\n'; |
| 945 } | 716 } |
| 946 | 717 |
| 947 class RenderTransform extends RenderProxyBox { | 718 class RenderTransform extends RenderProxyBox { |
| 948 RenderTransform({ | 719 RenderTransform({ |
| 949 Matrix4 transform, | 720 Matrix4 transform, |
| 950 RenderBox child | 721 RenderBox child |
| 951 }) : super(child) { | 722 }) : super(child) { |
| 952 assert(transform != null); | 723 assert(transform != null); |
| 953 this.transform = transform; | 724 this.transform = transform; |
| 954 } | 725 } |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1179 | 950 |
| 1180 void defaultPaint(RenderObjectDisplayList canvas) { | 951 void defaultPaint(RenderObjectDisplayList canvas) { |
| 1181 RenderBox child = firstChild; | 952 RenderBox child = firstChild; |
| 1182 while (child != null) { | 953 while (child != null) { |
| 1183 assert(child.parentData is ParentDataType); | 954 assert(child.parentData is ParentDataType); |
| 1184 canvas.paintChild(child, child.parentData.position); | 955 canvas.paintChild(child, child.parentData.position); |
| 1185 child = child.parentData.nextSibling; | 956 child = child.parentData.nextSibling; |
| 1186 } | 957 } |
| 1187 } | 958 } |
| 1188 } | 959 } |
| OLD | NEW |