Ви не можете вибрати більше 25 тем Теми мають розпочинатися з літери або цифри, можуть містити дефіси (-) і не повинні перевищувати 35 символів.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802
  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.ui.orderedlayout;
  17. import java.util.List;
  18. import com.google.gwt.aria.client.Roles;
  19. import com.google.gwt.core.client.GWT;
  20. import com.google.gwt.dom.client.Document;
  21. import com.google.gwt.dom.client.Element;
  22. import com.google.gwt.user.client.DOM;
  23. import com.google.gwt.user.client.Event;
  24. import com.google.gwt.user.client.Timer;
  25. import com.google.gwt.user.client.ui.SimplePanel;
  26. import com.google.gwt.user.client.ui.Widget;
  27. import com.vaadin.client.LayoutManager;
  28. import com.vaadin.client.StyleConstants;
  29. import com.vaadin.client.WidgetUtil;
  30. import com.vaadin.client.ui.FontIcon;
  31. import com.vaadin.client.ui.Icon;
  32. import com.vaadin.client.ui.ImageIcon;
  33. import com.vaadin.client.ui.layout.ElementResizeListener;
  34. import com.vaadin.shared.ui.AlignmentInfo;
  35. /**
  36. * Represents a slot which contains the actual widget in the layout.
  37. */
  38. public class Slot extends SimplePanel {
  39. private static final String ALIGN_CLASS_PREFIX = "v-align-";
  40. // this must be set at construction time and not changed afterwards
  41. private VAbstractOrderedLayout layout;
  42. public static final String SLOT_CLASSNAME = "v-slot";
  43. private Element spacer;
  44. private Element captionWrap;
  45. private Element caption;
  46. private Element captionText;
  47. private Icon icon;
  48. private Element errorIcon;
  49. private Element requiredIcon;
  50. private ElementResizeListener captionResizeListener;
  51. private ElementResizeListener widgetResizeListener;
  52. private ElementResizeListener spacingResizeListener;
  53. // Caption is placed after component unless there is some part which
  54. // moves it above.
  55. private CaptionPosition captionPosition = CaptionPosition.RIGHT;
  56. private AlignmentInfo alignment;
  57. private double expandRatio = -1;
  58. /**
  59. * Constructs a slot.
  60. *
  61. * When using this constructor, the layout and widget must be set before any
  62. * other operations are performed on the slot.
  63. *
  64. * @since 7.6
  65. */
  66. public Slot() {
  67. setStyleName(SLOT_CLASSNAME);
  68. }
  69. /**
  70. * Set the layout in which this slot is. This method must be called exactly
  71. * once at slot construction time when using the default constructor.
  72. *
  73. * The method should normally only be called by
  74. * {@link VAbstractOrderedLayout#createSlot(Widget)}.
  75. *
  76. * @since 7.6
  77. * @param layout
  78. * the layout containing the slot
  79. */
  80. public void setLayout(VAbstractOrderedLayout layout) {
  81. this.layout = layout;
  82. }
  83. /**
  84. * Constructs a slot.
  85. *
  86. * @param layout
  87. * The layout to which this slot belongs
  88. * @param widget
  89. * The widget to put in the slot
  90. * @deprecated use {@link GWT#create(Class)}, {@link #setWidget(Widget)} and
  91. * {@link #setLayout(VAbstractOrderedLayout)} instead
  92. */
  93. @Deprecated
  94. public Slot(VAbstractOrderedLayout layout, Widget widget) {
  95. setLayout(layout);
  96. setStyleName(SLOT_CLASSNAME);
  97. setWidget(widget);
  98. }
  99. /*
  100. * (non-Javadoc)
  101. *
  102. * @see com.google.gwt.user.client.ui.SimplePanel#remove(com.google.gwt.user
  103. * .client.ui.Widget)
  104. */
  105. @Override
  106. public boolean remove(Widget w) {
  107. detachListeners();
  108. return super.remove(w);
  109. }
  110. /*
  111. * (non-Javadoc)
  112. *
  113. * @see com.google.gwt.user.client.ui.SimplePanel#setWidget(com.google.gwt
  114. * .user.client.ui.Widget)
  115. */
  116. @Override
  117. public void setWidget(Widget w) {
  118. detachListeners();
  119. super.setWidget(w);
  120. attachListeners();
  121. }
  122. /**
  123. * Attaches resize listeners to the widget, caption and spacing elements
  124. */
  125. private void attachListeners() {
  126. if (getWidget() != null && layout.getLayoutManager() != null) {
  127. LayoutManager lm = layout.getLayoutManager();
  128. if (getCaptionElement() != null && captionResizeListener != null) {
  129. lm.addElementResizeListener(getCaptionElement(),
  130. captionResizeListener);
  131. }
  132. if (widgetResizeListener != null) {
  133. lm.addElementResizeListener(getWidget().getElement(),
  134. widgetResizeListener);
  135. }
  136. if (getSpacingElement() != null && spacingResizeListener != null) {
  137. lm.addElementResizeListener(getSpacingElement(),
  138. spacingResizeListener);
  139. }
  140. }
  141. }
  142. /**
  143. * Detaches resize listeners from the widget, caption and spacing elements
  144. */
  145. private void detachListeners() {
  146. if (getWidget() != null && layout.getLayoutManager() != null) {
  147. LayoutManager lm = layout.getLayoutManager();
  148. if (getCaptionElement() != null && captionResizeListener != null) {
  149. lm.removeElementResizeListener(getCaptionElement(),
  150. captionResizeListener);
  151. }
  152. if (widgetResizeListener != null) {
  153. lm.removeElementResizeListener(getWidget().getElement(),
  154. widgetResizeListener);
  155. }
  156. // in many cases, the listener has already been removed by
  157. // setSpacing(false)
  158. if (getSpacingElement() != null && spacingResizeListener != null) {
  159. lm.removeElementResizeListener(getSpacingElement(),
  160. spacingResizeListener);
  161. }
  162. }
  163. }
  164. public ElementResizeListener getCaptionResizeListener() {
  165. return captionResizeListener;
  166. }
  167. public void setCaptionResizeListener(
  168. ElementResizeListener captionResizeListener) {
  169. detachListeners();
  170. this.captionResizeListener = captionResizeListener;
  171. attachListeners();
  172. }
  173. public ElementResizeListener getWidgetResizeListener() {
  174. return widgetResizeListener;
  175. }
  176. public void setWidgetResizeListener(
  177. ElementResizeListener widgetResizeListener) {
  178. detachListeners();
  179. this.widgetResizeListener = widgetResizeListener;
  180. attachListeners();
  181. }
  182. public ElementResizeListener getSpacingResizeListener() {
  183. return spacingResizeListener;
  184. }
  185. public void setSpacingResizeListener(
  186. ElementResizeListener spacingResizeListener) {
  187. detachListeners();
  188. this.spacingResizeListener = spacingResizeListener;
  189. attachListeners();
  190. }
  191. /**
  192. * Returns the alignment for the slot
  193. *
  194. */
  195. public AlignmentInfo getAlignment() {
  196. return alignment;
  197. }
  198. /**
  199. * Sets the style names for the slot containing the widget
  200. *
  201. * @param stylenames
  202. * The style names for the slot
  203. */
  204. protected void setStyleNames(String... stylenames) {
  205. setStyleName(SLOT_CLASSNAME);
  206. if (stylenames != null) {
  207. for (String stylename : stylenames) {
  208. addStyleDependentName(stylename);
  209. }
  210. }
  211. // Ensure alignment style names are correct
  212. setAlignment(alignment);
  213. }
  214. /**
  215. * Sets how the widget is aligned inside the slot
  216. *
  217. * @param alignment
  218. * The alignment inside the slot
  219. */
  220. public void setAlignment(AlignmentInfo alignment) {
  221. this.alignment = alignment;
  222. if (alignment != null && alignment.isHorizontalCenter()) {
  223. addStyleName(ALIGN_CLASS_PREFIX + "center");
  224. removeStyleName(ALIGN_CLASS_PREFIX + "right");
  225. } else if (alignment != null && alignment.isRight()) {
  226. addStyleName(ALIGN_CLASS_PREFIX + "right");
  227. removeStyleName(ALIGN_CLASS_PREFIX + "center");
  228. } else {
  229. removeStyleName(ALIGN_CLASS_PREFIX + "right");
  230. removeStyleName(ALIGN_CLASS_PREFIX + "center");
  231. }
  232. if (alignment != null && alignment.isVerticalCenter()) {
  233. addStyleName(ALIGN_CLASS_PREFIX + "middle");
  234. removeStyleName(ALIGN_CLASS_PREFIX + "bottom");
  235. } else if (alignment != null && alignment.isBottom()) {
  236. addStyleName(ALIGN_CLASS_PREFIX + "bottom");
  237. removeStyleName(ALIGN_CLASS_PREFIX + "middle");
  238. } else {
  239. removeStyleName(ALIGN_CLASS_PREFIX + "middle");
  240. removeStyleName(ALIGN_CLASS_PREFIX + "bottom");
  241. }
  242. }
  243. /**
  244. * Set how the slot should be expanded relative to the other slots. 0 means
  245. * that the slot should not participate in the division of space based on
  246. * the expand ratios but instead be allocated space based on its natural
  247. * size. Other values causes the slot to get a share of the otherwise
  248. * unallocated space in proportion to the slot's expand ratio value.
  249. *
  250. * @param expandRatio
  251. * The ratio of the space the slot should occupy
  252. *
  253. */
  254. public void setExpandRatio(double expandRatio) {
  255. this.expandRatio = expandRatio;
  256. }
  257. /**
  258. * Get the expand ratio for the slot. The expand ratio describes how the
  259. * slot should be resized compared to other slots in the layout
  260. *
  261. * @return the expand ratio of the slot
  262. *
  263. * @see #setExpandRatio(double)
  264. */
  265. public double getExpandRatio() {
  266. return expandRatio;
  267. }
  268. /**
  269. * Set the spacing for the slot. The spacing determines if there should be
  270. * empty space around the slot when the slot.
  271. *
  272. * @param spacing
  273. * Should spacing be enabled
  274. */
  275. public void setSpacing(boolean spacing) {
  276. if (spacing && spacer == null) {
  277. spacer = DOM.createDiv();
  278. spacer.addClassName("v-spacing");
  279. /*
  280. * This has to be done here for the initial render. In other cases
  281. * where the spacer already exists onAttach will handle it.
  282. */
  283. getElement().getParentElement().insertBefore(spacer, getElement());
  284. } else if (!spacing && spacer != null) {
  285. // Remove listener before spacer to avoid memory leak
  286. LayoutManager lm = layout.getLayoutManager();
  287. if (lm != null && spacingResizeListener != null) {
  288. lm.removeElementResizeListener(spacer, spacingResizeListener);
  289. }
  290. spacer.removeFromParent();
  291. spacer = null;
  292. }
  293. }
  294. /**
  295. * Get the element which is added to make the spacing
  296. *
  297. * @return
  298. */
  299. public com.google.gwt.user.client.Element getSpacingElement() {
  300. return DOM.asOld(spacer);
  301. }
  302. /**
  303. * Does the slot have spacing
  304. */
  305. public boolean hasSpacing() {
  306. return getSpacingElement() != null;
  307. }
  308. /**
  309. * Get the vertical amount in pixels of the spacing
  310. */
  311. protected int getVerticalSpacing() {
  312. if (spacer == null) {
  313. return 0;
  314. } else if (layout.getLayoutManager() != null) {
  315. return layout.getLayoutManager().getOuterHeight(spacer);
  316. }
  317. return spacer.getOffsetHeight();
  318. }
  319. /**
  320. * Get the horizontal amount of pixels of the spacing
  321. *
  322. * @return
  323. */
  324. protected int getHorizontalSpacing() {
  325. if (spacer == null) {
  326. return 0;
  327. } else if (layout.getLayoutManager() != null) {
  328. return layout.getLayoutManager().getOuterWidth(spacer);
  329. }
  330. return spacer.getOffsetWidth();
  331. }
  332. /**
  333. * Set the position of the caption relative to the slot
  334. *
  335. * @param captionPosition
  336. * The position of the caption
  337. */
  338. public void setCaptionPosition(CaptionPosition captionPosition) {
  339. if (caption == null) {
  340. return;
  341. }
  342. captionWrap.removeClassName(
  343. "v-caption-on-" + this.captionPosition.name().toLowerCase());
  344. this.captionPosition = captionPosition;
  345. if (captionPosition == CaptionPosition.BOTTOM
  346. || captionPosition == CaptionPosition.RIGHT) {
  347. captionWrap.appendChild(caption);
  348. } else {
  349. captionWrap.insertFirst(caption);
  350. }
  351. captionWrap.addClassName(
  352. "v-caption-on-" + captionPosition.name().toLowerCase());
  353. }
  354. /**
  355. * Get the position of the caption relative to the slot
  356. */
  357. public CaptionPosition getCaptionPosition() {
  358. return captionPosition;
  359. }
  360. /**
  361. * Set the caption of the slot
  362. *
  363. * @param captionText
  364. * The text of the caption
  365. * @param iconUrl
  366. * The icon URL, must already be run trough translateVaadinUri()
  367. * @param styles
  368. * The style names
  369. * @param error
  370. * The error message
  371. * @param showError
  372. * Should the error message be shown
  373. * @param required
  374. * Is the (field) required
  375. * @param enabled
  376. * Is the component enabled
  377. *
  378. * @deprecated Use
  379. * {@link #setCaption(String, Icon, List, String, boolean, boolean, boolean)}
  380. * instead
  381. */
  382. @Deprecated
  383. public void setCaption(String captionText, String iconUrl,
  384. List<String> styles, String error, boolean showError,
  385. boolean required, boolean enabled) {
  386. Icon icon;
  387. if (FontIcon.isFontIconUri(iconUrl)) {
  388. icon = GWT.create(FontIcon.class);
  389. } else {
  390. icon = GWT.create(ImageIcon.class);
  391. }
  392. icon.setUri(iconUrl);
  393. setCaption(captionText, icon, styles, error, showError, required,
  394. enabled);
  395. }
  396. /**
  397. * Set the caption of the slot as text
  398. *
  399. * @param captionText
  400. * The text of the caption
  401. * @param icon
  402. * The icon
  403. * @param styles
  404. * The style names
  405. * @param error
  406. * The error message
  407. * @param showError
  408. * Should the error message be shown
  409. * @param required
  410. * Is the (field) required
  411. * @param enabled
  412. * Is the component enabled
  413. */
  414. public void setCaption(String captionText, Icon icon, List<String> styles,
  415. String error, boolean showError, boolean required,
  416. boolean enabled) {
  417. setCaption(captionText, icon, styles, error, showError, required,
  418. enabled, false);
  419. }
  420. /**
  421. * Set the caption of the slot
  422. *
  423. * @param captionText
  424. * The text of the caption
  425. * @param icon
  426. * The icon
  427. * @param styles
  428. * The style names
  429. * @param error
  430. * The error message
  431. * @param showError
  432. * Should the error message be shown
  433. * @param required
  434. * Is the (field) required
  435. * @param enabled
  436. * Is the component enabled
  437. * @param captionAsHtml
  438. * true if the caption should be rendered as HTML, false
  439. * otherwise
  440. */
  441. public void setCaption(String captionText, Icon icon, List<String> styles,
  442. String error, boolean showError, boolean required, boolean enabled,
  443. boolean captionAsHtml) {
  444. // TODO place for optimization: check if any of these have changed
  445. // since last time, and only run those changes
  446. // Caption wrappers
  447. Widget widget = getWidget();
  448. final Element focusedElement = WidgetUtil.getFocusedElement();
  449. // By default focus will not be lost
  450. boolean focusLost = false;
  451. if (captionText != null || icon != null || error != null || required) {
  452. if (caption == null) {
  453. caption = DOM.createDiv();
  454. captionWrap = DOM.createDiv();
  455. captionWrap.addClassName(StyleConstants.UI_WIDGET);
  456. captionWrap.addClassName("v-has-caption");
  457. getElement().appendChild(captionWrap);
  458. orphan(widget);
  459. captionWrap.appendChild(widget.getElement());
  460. adopt(widget);
  461. // Made changes to DOM. Focus can be lost if it was in the
  462. // widget.
  463. focusLost = (focusedElement == null ? false
  464. : widget.getElement().isOrHasChild(focusedElement));
  465. }
  466. } else if (caption != null) {
  467. orphan(widget);
  468. getElement().appendChild(widget.getElement());
  469. adopt(widget);
  470. captionWrap.removeFromParent();
  471. caption = null;
  472. captionWrap = null;
  473. // Made changes to DOM. Focus can be lost if it was in the widget.
  474. focusLost = (focusedElement == null ? false
  475. : widget.getElement().isOrHasChild(focusedElement));
  476. }
  477. // Caption text
  478. if (captionText != null) {
  479. if (this.captionText == null) {
  480. this.captionText = DOM.createSpan();
  481. this.captionText.addClassName("v-captiontext");
  482. caption.appendChild(this.captionText);
  483. }
  484. if (captionText.trim().equals("")) {
  485. this.captionText.setInnerHTML("&nbsp;");
  486. } else {
  487. if (captionAsHtml) {
  488. this.captionText.setInnerHTML(captionText);
  489. } else {
  490. this.captionText.setInnerText(captionText);
  491. }
  492. }
  493. } else if (this.captionText != null) {
  494. this.captionText.removeFromParent();
  495. this.captionText = null;
  496. }
  497. // Icon
  498. if (this.icon != null) {
  499. this.icon.getElement().removeFromParent();
  500. }
  501. if (icon != null) {
  502. caption.insertFirst(icon.getElement());
  503. }
  504. this.icon = icon;
  505. // Required
  506. if (required) {
  507. if (requiredIcon == null) {
  508. requiredIcon = DOM.createSpan();
  509. // TODO decide something better (e.g. use CSS to insert the
  510. // character)
  511. requiredIcon.setInnerHTML("*");
  512. requiredIcon.setClassName("v-required-field-indicator");
  513. // The star should not be read by the screen reader, as it is
  514. // purely visual. Required state is set at the element level for
  515. // the screen reader.
  516. Roles.getTextboxRole().setAriaHiddenState(requiredIcon, true);
  517. }
  518. caption.appendChild(requiredIcon);
  519. } else if (requiredIcon != null) {
  520. requiredIcon.removeFromParent();
  521. requiredIcon = null;
  522. }
  523. // Error
  524. if (error != null && showError) {
  525. if (errorIcon == null) {
  526. errorIcon = DOM.createSpan();
  527. errorIcon.setClassName("v-errorindicator");
  528. }
  529. caption.appendChild(errorIcon);
  530. } else if (errorIcon != null) {
  531. errorIcon.removeFromParent();
  532. errorIcon = null;
  533. }
  534. if (caption != null) {
  535. // Styles
  536. caption.setClassName("v-caption");
  537. if (styles != null) {
  538. for (String style : styles) {
  539. caption.addClassName("v-caption-" + style);
  540. }
  541. }
  542. if (enabled) {
  543. caption.removeClassName("v-disabled");
  544. } else {
  545. caption.addClassName("v-disabled");
  546. }
  547. // Caption position
  548. if (captionText != null || icon != null) {
  549. setCaptionPosition(CaptionPosition.TOP);
  550. } else {
  551. setCaptionPosition(CaptionPosition.RIGHT);
  552. }
  553. }
  554. if (focusLost) {
  555. // Find out what element is currently focused.
  556. Element currentFocus = WidgetUtil.getFocusedElement();
  557. if (currentFocus != null
  558. && currentFocus.equals(Document.get().getBody())) {
  559. // Focus has moved to BodyElement and should be moved back to
  560. // original location. This happened because of adding or
  561. // removing the captionWrap
  562. focusedElement.focus();
  563. } else if (currentFocus != focusedElement) {
  564. // Focus is either moved somewhere else on purpose or IE has
  565. // lost it. Investigate further.
  566. Timer focusTimer = new Timer() {
  567. @Override
  568. public void run() {
  569. if (WidgetUtil.getFocusedElement() == null) {
  570. // This should never become an infinite loop and
  571. // even if it does it will be stopped once something
  572. // is done with the browser.
  573. schedule(25);
  574. } else if (WidgetUtil.getFocusedElement()
  575. .equals(Document.get().getBody())) {
  576. // Focus found it's way to BodyElement. Now it can
  577. // be restored
  578. focusedElement.focus();
  579. }
  580. }
  581. };
  582. // Newer IE versions can handle things immediately.
  583. focusTimer.run();
  584. }
  585. }
  586. }
  587. /**
  588. * Does the slot have a caption
  589. */
  590. public boolean hasCaption() {
  591. return caption != null;
  592. }
  593. /**
  594. * Get the slots caption element
  595. */
  596. public com.google.gwt.user.client.Element getCaptionElement() {
  597. return DOM.asOld(caption);
  598. }
  599. private boolean relativeWidth = false;
  600. /**
  601. * Set if the slot has a relative width
  602. *
  603. * @param relativeWidth
  604. * True if slot uses relative width, false if the slot has a
  605. * static width
  606. */
  607. public void setRelativeWidth(boolean relativeWidth) {
  608. this.relativeWidth = relativeWidth;
  609. updateRelativeSize(relativeWidth, "width");
  610. }
  611. public boolean hasRelativeWidth() {
  612. return relativeWidth;
  613. }
  614. private boolean relativeHeight = false;
  615. /**
  616. * Set if the slot has a relative height
  617. *
  618. * @param relativeHeight
  619. * True if the slot uses a relative height, false if the slot has
  620. * a static height
  621. */
  622. public void setRelativeHeight(boolean relativeHeight) {
  623. this.relativeHeight = relativeHeight;
  624. updateRelativeSize(relativeHeight, "height");
  625. }
  626. public boolean hasRelativeHeight() {
  627. return relativeHeight;
  628. }
  629. /**
  630. * Updates the captions size if the slot is relative
  631. *
  632. * @param isRelativeSize
  633. * Is the slot relatively sized
  634. * @param direction
  635. * The direction of the caption
  636. */
  637. private void updateRelativeSize(boolean isRelativeSize, String direction) {
  638. if (isRelativeSize && hasCaption()) {
  639. captionWrap.getStyle().setProperty(direction,
  640. getWidget().getElement().getStyle().getProperty(direction));
  641. captionWrap.addClassName("v-has-" + direction);
  642. } else if (hasCaption()) {
  643. if (direction.equals("height")) {
  644. captionWrap.getStyle().clearHeight();
  645. } else {
  646. captionWrap.getStyle().clearWidth();
  647. }
  648. captionWrap.removeClassName("v-has-" + direction);
  649. captionWrap.getStyle().clearPaddingTop();
  650. captionWrap.getStyle().clearPaddingRight();
  651. captionWrap.getStyle().clearPaddingBottom();
  652. captionWrap.getStyle().clearPaddingLeft();
  653. caption.getStyle().clearMarginTop();
  654. caption.getStyle().clearMarginRight();
  655. caption.getStyle().clearMarginBottom();
  656. caption.getStyle().clearMarginLeft();
  657. }
  658. }
  659. /*
  660. * (non-Javadoc)
  661. *
  662. * @see com.google.gwt.user.client.ui.Widget#onBrowserEvent(com.google.gwt
  663. * .user.client.Event)
  664. */
  665. @Override
  666. public void onBrowserEvent(Event event) {
  667. super.onBrowserEvent(event);
  668. if (DOM.eventGetType(event) == Event.ONLOAD && icon != null
  669. && icon.getElement() == DOM.eventGetTarget(event)) {
  670. if (layout.getLayoutManager() != null) {
  671. layout.getLayoutManager().layoutLater();
  672. } else {
  673. layout.updateCaptionOffset(caption);
  674. }
  675. }
  676. }
  677. /*
  678. * (non-Javadoc)
  679. *
  680. * @see com.google.gwt.user.client.ui.SimplePanel#getContainerElement()
  681. */
  682. @Override
  683. protected com.google.gwt.user.client.Element getContainerElement() {
  684. if (captionWrap == null) {
  685. return getElement();
  686. } else {
  687. return DOM.asOld(captionWrap);
  688. }
  689. }
  690. /*
  691. * (non-Javadoc)
  692. *
  693. * @see com.google.gwt.user.client.ui.Widget#onDetach()
  694. */
  695. @Override
  696. protected void onDetach() {
  697. if (spacer != null) {
  698. spacer.removeFromParent();
  699. }
  700. super.onDetach();
  701. }
  702. /*
  703. * (non-Javadoc)
  704. *
  705. * @see com.google.gwt.user.client.ui.Widget#onAttach()
  706. */
  707. @Override
  708. protected void onAttach() {
  709. super.onAttach();
  710. if (spacer != null) {
  711. getElement().getParentElement().insertBefore(spacer, getElement());
  712. }
  713. }
  714. public boolean isRelativeInDirection(boolean vertical) {
  715. if (vertical) {
  716. return hasRelativeHeight();
  717. } else {
  718. return hasRelativeWidth();
  719. }
  720. }
  721. }