You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
пре 12 година
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299
  1. /*
  2. * Copyright 2000-2016 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.client;
  17. import java.util.logging.Logger;
  18. import com.google.gwt.core.client.JsArrayString;
  19. import com.google.gwt.dom.client.Element;
  20. public class MeasuredSize {
  21. private final static boolean debugSizeChanges = false;
  22. public static class MeasureResult {
  23. private final boolean widthChanged;
  24. private final boolean heightChanged;
  25. private MeasureResult(boolean widthChanged, boolean heightChanged) {
  26. this.widthChanged = widthChanged;
  27. this.heightChanged = heightChanged;
  28. }
  29. public boolean isHeightChanged() {
  30. return heightChanged;
  31. }
  32. public boolean isWidthChanged() {
  33. return widthChanged;
  34. }
  35. public boolean isChanged() {
  36. return heightChanged || widthChanged;
  37. }
  38. }
  39. private double width = -1;
  40. private double height = -1;
  41. private int[] paddings = new int[4];
  42. private int[] borders = new int[4];
  43. private int[] margins = new int[4];
  44. private FastStringSet dependents = FastStringSet.create();
  45. public double getOuterHeight() {
  46. return height;
  47. }
  48. public double getOuterWidth() {
  49. return width;
  50. }
  51. public void addDependent(String pid) {
  52. dependents.add(pid);
  53. }
  54. public void removeDependent(String pid) {
  55. dependents.remove(pid);
  56. }
  57. public boolean hasDependents() {
  58. return !dependents.isEmpty();
  59. }
  60. public JsArrayString getDependents() {
  61. return dependents.dump();
  62. }
  63. private static int sumWidths(int[] sizes) {
  64. return sizes[1] + sizes[3];
  65. }
  66. private static int sumHeights(int[] sizes) {
  67. return sizes[0] + sizes[2];
  68. }
  69. public double getInnerHeight() {
  70. return height - sumHeights(margins) - sumHeights(borders)
  71. - sumHeights(paddings);
  72. }
  73. public double getInnerWidth() {
  74. return width - sumWidths(margins) - sumWidths(borders)
  75. - sumWidths(paddings);
  76. }
  77. public boolean setOuterHeight(double height) {
  78. if (this.height != height) {
  79. this.height = height;
  80. return true;
  81. } else {
  82. return false;
  83. }
  84. }
  85. public boolean setOuterWidth(double width) {
  86. if (this.width != width) {
  87. this.width = width;
  88. return true;
  89. } else {
  90. return false;
  91. }
  92. }
  93. public int getBorderHeight() {
  94. return sumHeights(borders);
  95. }
  96. public int getBorderWidth() {
  97. return sumWidths(borders);
  98. }
  99. public int getPaddingHeight() {
  100. return sumHeights(paddings);
  101. }
  102. public int getPaddingWidth() {
  103. return sumWidths(paddings);
  104. }
  105. public int getMarginHeight() {
  106. return sumHeights(margins);
  107. }
  108. public int getMarginWidth() {
  109. return sumWidths(margins);
  110. }
  111. public int getMarginTop() {
  112. return margins[0];
  113. }
  114. public int getMarginRight() {
  115. return margins[1];
  116. }
  117. public int getMarginBottom() {
  118. return margins[2];
  119. }
  120. public int getMarginLeft() {
  121. return margins[3];
  122. }
  123. public int getBorderTop() {
  124. return borders[0];
  125. }
  126. public int getBorderRight() {
  127. return borders[1];
  128. }
  129. public int getBorderBottom() {
  130. return borders[2];
  131. }
  132. public int getBorderLeft() {
  133. return borders[3];
  134. }
  135. public int getPaddingTop() {
  136. return paddings[0];
  137. }
  138. public int getPaddingRight() {
  139. return paddings[1];
  140. }
  141. public int getPaddingBottom() {
  142. return paddings[2];
  143. }
  144. public int getPaddingLeft() {
  145. return paddings[3];
  146. }
  147. public MeasureResult measure(Element element) {
  148. Profiler.enter("MeasuredSize.measure");
  149. boolean heightChanged = false;
  150. boolean widthChanged = false;
  151. Profiler.enter("new ComputedStyle");
  152. ComputedStyle computedStyle = new ComputedStyle(element);
  153. int[] paddings = computedStyle.getPadding();
  154. // Some browsers do not reflow until accessing data from the computed
  155. // style object
  156. Profiler.leave("new ComputedStyle");
  157. Profiler.enter("Measure paddings");
  158. if (!heightChanged && hasHeightChanged(this.paddings, paddings)) {
  159. debugSizeChange(element, "Height (padding)", this.paddings,
  160. paddings);
  161. heightChanged = true;
  162. }
  163. if (!widthChanged && hasWidthChanged(this.paddings, paddings)) {
  164. debugSizeChange(element, "Width (padding)", this.paddings,
  165. paddings);
  166. widthChanged = true;
  167. }
  168. this.paddings = paddings;
  169. Profiler.leave("Measure paddings");
  170. Profiler.enter("Measure margins");
  171. int[] margins = computedStyle.getMargin();
  172. if (!heightChanged && hasHeightChanged(this.margins, margins)) {
  173. debugSizeChange(element, "Height (margins)", this.margins, margins);
  174. heightChanged = true;
  175. }
  176. if (!widthChanged && hasWidthChanged(this.margins, margins)) {
  177. debugSizeChange(element, "Width (margins)", this.margins, margins);
  178. widthChanged = true;
  179. }
  180. this.margins = margins;
  181. Profiler.leave("Measure margins");
  182. Profiler.enter("Measure borders");
  183. int[] borders = computedStyle.getBorder();
  184. if (!heightChanged && hasHeightChanged(this.borders, borders)) {
  185. debugSizeChange(element, "Height (borders)", this.borders, borders);
  186. heightChanged = true;
  187. }
  188. if (!widthChanged && hasWidthChanged(this.borders, borders)) {
  189. debugSizeChange(element, "Width (borders)", this.borders, borders);
  190. widthChanged = true;
  191. }
  192. this.borders = borders;
  193. Profiler.leave("Measure borders");
  194. Profiler.enter("Measure height");
  195. double requiredHeight = WidgetUtil.getRequiredHeightDouble(element);
  196. double outerHeight = requiredHeight + sumHeights(margins);
  197. double oldHeight = height;
  198. if (setOuterHeight(outerHeight)) {
  199. debugSizeChange(element, "Height (outer)", oldHeight, height);
  200. heightChanged = true;
  201. }
  202. Profiler.leave("Measure height");
  203. Profiler.enter("Measure width");
  204. double requiredWidth = WidgetUtil.getRequiredWidthDouble(element);
  205. double outerWidth = requiredWidth + sumWidths(margins);
  206. double oldWidth = width;
  207. if (setOuterWidth(outerWidth)) {
  208. debugSizeChange(element, "Width (outer)", oldWidth, width);
  209. widthChanged = true;
  210. }
  211. Profiler.leave("Measure width");
  212. Profiler.leave("MeasuredSize.measure");
  213. return new MeasureResult(widthChanged, heightChanged);
  214. }
  215. private void debugSizeChange(Element element, String sizeChangeType,
  216. int[] changedFrom, int[] changedTo) {
  217. debugSizeChange(element, sizeChangeType,
  218. java.util.Arrays.asList(changedFrom).toString(),
  219. java.util.Arrays.asList(changedTo).toString());
  220. }
  221. private void debugSizeChange(Element element, String sizeChangeType,
  222. double changedFrom, double changedTo) {
  223. debugSizeChange(element, sizeChangeType, String.valueOf(changedFrom),
  224. String.valueOf(changedTo));
  225. }
  226. private void debugSizeChange(Element element, String sizeChangeType,
  227. String changedFrom, String changedTo) {
  228. if (debugSizeChanges) {
  229. getLogger().info(sizeChangeType + " has changed from " + changedFrom
  230. + " to " + changedTo + " for " + element.toString());
  231. }
  232. }
  233. private static boolean hasWidthChanged(int[] sizes1, int[] sizes2) {
  234. return sizes1[1] != sizes2[1] || sizes1[3] != sizes2[3];
  235. }
  236. private static boolean hasHeightChanged(int[] sizes1, int[] sizes2) {
  237. return sizes1[0] != sizes2[0] || sizes1[2] != sizes2[2];
  238. }
  239. private static Logger getLogger() {
  240. return Logger.getLogger(MeasuredSize.class.getName());
  241. }
  242. }