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.

Util.java 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. /*
  2. @ITMillApache2LicenseForJavaFiles@
  3. */
  4. package com.itmill.toolkit.terminal.gwt.client;
  5. import java.util.HashMap;
  6. import java.util.HashSet;
  7. import java.util.Map;
  8. import java.util.Set;
  9. import com.google.gwt.user.client.DOM;
  10. import com.google.gwt.user.client.Element;
  11. import com.google.gwt.user.client.ui.RootPanel;
  12. import com.google.gwt.user.client.ui.Widget;
  13. public class Util {
  14. /**
  15. * Helper method for debugging purposes.
  16. *
  17. * Stops execution on firefox browsers on a breakpoint.
  18. *
  19. */
  20. public static native void browserDebugger()
  21. /*-{
  22. if($wnd.console)
  23. debugger;
  24. }-*/;
  25. /**
  26. * Called when the size of one or more widgets have changed during
  27. * rendering. Finds parent container and notifies them of the size change.
  28. *
  29. * @param widgets
  30. */
  31. public static void componentSizeUpdated(Set<Widget> widgets) {
  32. if (widgets.isEmpty()) {
  33. return;
  34. }
  35. Map<Container, Set<Paintable>> childWidgets = new HashMap<Container, Set<Paintable>>();
  36. for (Widget widget : widgets) {
  37. Widget parent = widget.getParent();
  38. while (parent != null && !(parent instanceof Container)) {
  39. parent = parent.getParent();
  40. }
  41. if (parent != null) {
  42. Set<Paintable> set = childWidgets.get(parent);
  43. if (set == null) {
  44. set = new HashSet<Paintable>();
  45. childWidgets.put((Container) parent, set);
  46. }
  47. set.add((Paintable) widget);
  48. }
  49. }
  50. Set<Widget> parentChanges = new HashSet<Widget>();
  51. for (Container parent : childWidgets.keySet()) {
  52. if (!parent.requestLayout(childWidgets.get(parent))) {
  53. parentChanges.add((Widget) parent);
  54. }
  55. }
  56. componentSizeUpdated(parentChanges);
  57. }
  58. public static float parseRelativeSize(String size) {
  59. if (size == null || !size.endsWith("%")) {
  60. return -1;
  61. }
  62. try {
  63. return Float.parseFloat(size.substring(0, size.length() - 1));
  64. } catch (Exception e) {
  65. ClientExceptionHandler.displayError(
  66. "Unable to parse relative size", e);
  67. }
  68. return -1;
  69. }
  70. /**
  71. * Returns closest parent Widget in hierarchy that implements Container
  72. * interface
  73. *
  74. * @param component
  75. * @return closest parent Container
  76. */
  77. public static Container getLayout(Widget component) {
  78. Widget parent = component.getParent();
  79. while (parent != null && !(parent instanceof Container)) {
  80. parent = parent.getParent();
  81. }
  82. if (parent != null) {
  83. assert ((Container) parent).hasChildComponent(component);
  84. return (Container) parent;
  85. }
  86. return null;
  87. }
  88. /**
  89. * Detects if current browser is IE.
  90. *
  91. * @deprecated use BrowserInfo class instead
  92. *
  93. * @return true if IE
  94. */
  95. public static boolean isIE() {
  96. return BrowserInfo.get().isIE();
  97. }
  98. /**
  99. * Detects if current browser is IE6.
  100. *
  101. * @deprecated use BrowserInfo class instead
  102. *
  103. * @return true if IE6
  104. */
  105. public static boolean isIE6() {
  106. return BrowserInfo.get().isIE6();
  107. }
  108. /**
  109. * @deprecated use BrowserInfo class instead
  110. * @return
  111. */
  112. public static boolean isIE7() {
  113. return BrowserInfo.get().isIE7();
  114. }
  115. /**
  116. * @deprecated use BrowserInfo class instead
  117. * @return
  118. */
  119. public static boolean isFF2() {
  120. return BrowserInfo.get().isFF2();
  121. }
  122. private static final Element escapeHtmlHelper = DOM.createDiv();
  123. /**
  124. * Converts html entities to text.
  125. *
  126. * @param html
  127. * @return escaped string presentation of given html
  128. */
  129. public static String escapeHTML(String html) {
  130. DOM.setInnerText(escapeHtmlHelper, html);
  131. return DOM.getInnerHTML(escapeHtmlHelper);
  132. }
  133. /**
  134. * Adds transparent PNG fix to image element; only use for IE6.
  135. *
  136. * @param el
  137. * IMG element
  138. * @param blankImageUrl
  139. * URL to transparent one-pixel gif
  140. */
  141. public native static void addPngFix(Element el, String blankImageUrl)
  142. /*-{
  143. el.attachEvent("onload", function() {
  144. var src = el.src;
  145. if (src.indexOf(".png")<1) return;
  146. var w = el.width||16;
  147. var h = el.height||16;
  148. el.src =blankImageUrl;
  149. el.style.height = h+"px";
  150. el.style.width = w+"px";
  151. el.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+src+"', sizingMethod='crop');";
  152. },false);
  153. }-*/;
  154. /**
  155. * Clones given element as in JavaScript.
  156. *
  157. * Deprecate this if there appears similar method into GWT someday.
  158. *
  159. * @param element
  160. * @param deep
  161. * clone child tree also
  162. * @return
  163. */
  164. public static native Element cloneNode(Element element, boolean deep)
  165. /*-{
  166. return element.cloneNode(deep);
  167. }-*/;
  168. public static int measureHorizontalPadding(Element element, int paddingGuess) {
  169. String originalWidth = DOM.getStyleAttribute(element, "width");
  170. int originalOffsetWidth = element.getOffsetWidth();
  171. int widthGuess = (originalOffsetWidth + paddingGuess);
  172. DOM.setStyleAttribute(element, "width", widthGuess + "px");
  173. int padding = widthGuess - element.getOffsetWidth();
  174. DOM.setStyleAttribute(element, "width", originalWidth);
  175. return padding;
  176. }
  177. public static void setWidthExcludingPadding(Element element,
  178. int requestedWidth, int paddingGuess) {
  179. int widthGuess = requestedWidth - paddingGuess;
  180. if (widthGuess < 0) {
  181. widthGuess = 0;
  182. }
  183. DOM.setStyleAttribute(element, "width", widthGuess + "px");
  184. int captionOffsetWidth = DOM.getElementPropertyInt(element,
  185. "offsetWidth");
  186. int actualPadding = captionOffsetWidth - widthGuess;
  187. if (actualPadding != paddingGuess) {
  188. DOM.setStyleAttribute(element, "width", requestedWidth
  189. - actualPadding + "px");
  190. }
  191. }
  192. private static int detectedScrollbarSize = -1;
  193. public static int getNativeScrollbarSize() {
  194. if (detectedScrollbarSize < 0) {
  195. Element scroller = DOM.createDiv();
  196. scroller.getStyle().setProperty("width", "50px");
  197. scroller.getStyle().setProperty("height", "50px");
  198. scroller.getStyle().setProperty("overflow", "scroll");
  199. scroller.getStyle().setProperty("position", "absolute");
  200. scroller.getStyle().setProperty("marginLeft", "-5000px");
  201. RootPanel.getBodyElement().appendChild(scroller);
  202. detectedScrollbarSize = scroller.getOffsetWidth()
  203. - scroller.getPropertyInt("clientWidth");
  204. assert detectedScrollbarSize != 0;
  205. RootPanel.getBodyElement().removeChild(scroller);
  206. }
  207. return detectedScrollbarSize;
  208. }
  209. }