| OLD | NEW |
| 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 /** The interface that the layout algorithms use to talk to the view. */ | 5 /** The interface that the layout algorithms use to talk to the view. */ |
| 6 interface Positionable { | 6 interface Positionable { |
| 7 ViewLayout get layout(); | 7 ViewLayout get layout(); |
| 8 | 8 |
| 9 /** Gets our custom CSS properties, as provided by the CSS preprocessor. */ | 9 /** Gets our custom CSS properties, as provided by the CSS preprocessor. */ |
| 10 Map<String, String> get customStyle(); | 10 Map<String, String> get customStyle(); |
| 11 | 11 |
| 12 /** Gets the root DOM used for layout. */ | 12 /** Gets the root DOM used for layout. */ |
| 13 Element get node(); | 13 Element get node(); |
| 14 | 14 |
| 15 /** Gets the collection of child views. */ | 15 /** Gets the collection of child views. */ |
| 16 Collection<Positionable> get childViews(); | 16 Collection<Positionable> get childViews(); |
| 17 | 17 |
| 18 /** Causes a view to layout its children. */ | 18 /** Causes a view to layout its children. */ |
| 19 void doLayout(); | 19 void doLayout(); |
| 20 } | 20 } |
| 21 | 21 |
| 22 | 22 |
| 23 /** | 23 /** |
| 24 * Caches the layout parameters that were specified in CSS during a layout | 24 * Caches the layout parameters that were specified in CSS during a layout |
| 25 * computation. These values are immutable during a layout. | 25 * computation. These values are immutable during a layout. |
| 26 */ | 26 */ |
| 27 class LayoutParams { | 27 class LayoutParams { |
| 28 // TODO(jmesserly): should be const, but there's a bug in DartC preventing us | 28 // TODO(jmesserly): should be const, but there's a bug in DartC preventing us |
| 29 // from calling "window." in an initializer. See b/5332777 | 29 // from calling "window." in an initializer. See b/5332777 |
| 30 Css style; | 30 CSSStyleDeclaration style; |
| 31 | 31 |
| 32 int get layer() => 0; | 32 int get layer() => 0; |
| 33 | 33 |
| 34 LayoutParams(Element node) { | 34 LayoutParams(Element node) { |
| 35 style = new Css(window.getComputedStyle(node, '')); | 35 style = window.getComputedStyle(node, ''); |
| 36 } | 36 } |
| 37 } | 37 } |
| 38 | 38 |
| 39 // TODO(jmesserly): enums would really help here | 39 // TODO(jmesserly): enums would really help here |
| 40 class Dimension { | 40 class Dimension { |
| 41 // TODO(jmesserly): perhaps this should be X and Y | 41 // TODO(jmesserly): perhaps this should be X and Y |
| 42 static final WIDTH = const Dimension._internal('width'); | 42 static final WIDTH = const Dimension._internal('width'); |
| 43 static final HEIGHT = const Dimension._internal('height'); | 43 static final HEIGHT = const Dimension._internal('height'); |
| 44 | 44 |
| 45 final String name; // for debugging | 45 final String name; // for debugging |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 return new GridLayout(view); | 94 return new GridLayout(view); |
| 95 } else { | 95 } else { |
| 96 return new ViewLayout(view); | 96 return new ViewLayout(view); |
| 97 } | 97 } |
| 98 } | 98 } |
| 99 | 99 |
| 100 static bool hasCustomLayout(Positionable view) { | 100 static bool hasCustomLayout(Positionable view) { |
| 101 return view.customStyle['display'] == "-dart-grid"; | 101 return view.customStyle['display'] == "-dart-grid"; |
| 102 } | 102 } |
| 103 | 103 |
| 104 Css get _style() => layoutParams.style; | 104 CSSStyleDeclaration get _style() => layoutParams.style; |
| 105 | 105 |
| 106 int get currentWidth() => view.node.offsetWidth; | 106 int get currentWidth() => view.node.offsetWidth; |
| 107 int get currentHeight() => view.node.offsetHeight; | 107 int get currentHeight() => view.node.offsetHeight; |
| 108 | 108 |
| 109 int get borderLeftWidth() => _toPixels(_style.borderLeftWidth); | 109 int get borderLeftWidth() => _toPixels(_style.borderLeftWidth); |
| 110 int get borderTopWidth() => _toPixels(_style.borderTopWidth); | 110 int get borderTopWidth() => _toPixels(_style.borderTopWidth); |
| 111 int get borderRightWidth() => _toPixels(_style.borderRightWidth); | 111 int get borderRightWidth() => _toPixels(_style.borderRightWidth); |
| 112 int get borderBottomWidth() => _toPixels(_style.borderBottomWidth); | 112 int get borderBottomWidth() => _toPixels(_style.borderBottomWidth); |
| 113 int get borderWidth() => borderLeftWidth + borderRightWidth; | 113 int get borderWidth() => borderLeftWidth + borderRightWidth; |
| 114 int get borderHeight() => borderTopWidth + borderBottomWidth; | 114 int get borderHeight() => borderTopWidth + borderBottomWidth; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 130 _measuredWidth = width - borderWidth; | 130 _measuredWidth = width - borderWidth; |
| 131 _measuredHeight = height - borderHeight; | 131 _measuredHeight = height - borderHeight; |
| 132 | 132 |
| 133 measureLayout(_measuredWidth, _measuredHeight); | 133 measureLayout(_measuredWidth, _measuredHeight); |
| 134 } | 134 } |
| 135 | 135 |
| 136 /** Applies the layout to the node. */ | 136 /** Applies the layout to the node. */ |
| 137 void applyLayout() { | 137 void applyLayout() { |
| 138 if (_measuredLeft != null) { | 138 if (_measuredLeft != null) { |
| 139 // TODO(jmesserly): benchmark the performance of this DOM interaction | 139 // TODO(jmesserly): benchmark the performance of this DOM interaction |
| 140 final css = new Css(view.node.style); | 140 final style = view.node.style; |
| 141 css.position = 'absolute'; | 141 style.position = 'absolute'; |
| 142 css.left = '${_measuredLeft}px'; | 142 style.left = '${_measuredLeft}px'; |
| 143 css.top = '${_measuredTop}px'; | 143 style.top = '${_measuredTop}px'; |
| 144 css.width = '${_measuredWidth}px'; | 144 style.width = '${_measuredWidth}px'; |
| 145 css.height = '${_measuredHeight}px'; | 145 style.height = '${_measuredHeight}px'; |
| 146 css.zIndex = '${layoutParams.layer}'; | 146 style.zIndex = '${layoutParams.layer}'; |
| 147 | 147 |
| 148 _measuredLeft = null; | 148 _measuredLeft = null; |
| 149 _measuredTop = null; | 149 _measuredTop = null; |
| 150 _measuredWidth = null; | 150 _measuredWidth = null; |
| 151 _measuredHeight = null; | 151 _measuredHeight = null; |
| 152 | 152 |
| 153 // Ensure we can handle our custom layout when it is a child of a | 153 // Ensure we can handle our custom layout when it is a child of a |
| 154 // DOM-positioned node. For example, say we have a View tree like this: | 154 // DOM-positioned node. For example, say we have a View tree like this: |
| 155 // | 155 // |
| 156 // ViewWithLayout <-- uses our layout engine | 156 // ViewWithLayout <-- uses our layout engine |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 216 // For an unset max-content size, use the actual size | 216 // For an unset max-content size, use the actual size |
| 217 return size; | 217 return size; |
| 218 } | 218 } |
| 219 if (style.endsWith('%')) { | 219 if (style.endsWith('%')) { |
| 220 num percent = Math.parseDouble(style.substring(0, style.length - 1)); | 220 num percent = Math.parseDouble(style.substring(0, style.length - 1)); |
| 221 return ((percent / 100) * parentSize).toInt(); | 221 return ((percent / 100) * parentSize).toInt(); |
| 222 } | 222 } |
| 223 return _toPixels(style); | 223 return _toPixels(style); |
| 224 } | 224 } |
| 225 } | 225 } |
| OLD | NEW |