diff options
author | Jonatan Kronqvist <jonatan.kronqvist@itmill.com> | 2011-05-02 08:17:50 +0000 |
---|---|---|
committer | Jonatan Kronqvist <jonatan.kronqvist@itmill.com> | 2011-05-02 08:17:50 +0000 |
commit | eec70d976c766b61449ef701b07fec707ea3006b (patch) | |
tree | 4995cdeffd88c6ca007fc34049ade0b868f5c650 /src | |
parent | 9d6d01502b811a1a1a5d383c875895e82cbe0ffc (diff) | |
download | vaadin-framework-eec70d976c766b61449ef701b07fec707ea3006b.tar.gz vaadin-framework-eec70d976c766b61449ef701b07fec707ea3006b.zip |
Fix for #6841 - Tree no longer scrolls horizontally on selection.
svn changeset:18573/svn branch:6.6
Diffstat (limited to 'src')
-rw-r--r-- | src/com/vaadin/terminal/gwt/client/ui/FocusElementPanel.java | 82 | ||||
-rw-r--r-- | src/com/vaadin/terminal/gwt/client/ui/VTree.java | 54 |
2 files changed, 124 insertions, 12 deletions
diff --git a/src/com/vaadin/terminal/gwt/client/ui/FocusElementPanel.java b/src/com/vaadin/terminal/gwt/client/ui/FocusElementPanel.java new file mode 100644 index 0000000000..fe4b483798 --- /dev/null +++ b/src/com/vaadin/terminal/gwt/client/ui/FocusElementPanel.java @@ -0,0 +1,82 @@ +package com.vaadin.terminal.gwt.client.ui; + +import com.google.gwt.dom.client.DivElement; +import com.google.gwt.dom.client.Document; +import com.google.gwt.dom.client.Style; +import com.google.gwt.dom.client.Style.Position; +import com.google.gwt.dom.client.Style.Unit; +import com.google.gwt.user.client.DOM; +import com.google.gwt.user.client.Element; +import com.google.gwt.user.client.Event; +import com.google.gwt.user.client.ui.Widget; +import com.google.gwt.user.client.ui.impl.FocusImpl; +import com.vaadin.terminal.gwt.client.BrowserInfo; + +/** + * A panel that contains an always visible 0x0 size element that holds the focus + * for all browsers but IE6. + */ +public class FocusElementPanel extends SimpleFocusablePanel { + + private DivElement focusElement; + + public FocusElementPanel() { + focusElement = Document.get().createDivElement(); + } + + @Override + public void setWidget(Widget w) { + super.setWidget(w); + if (!BrowserInfo.get().isIE6()) { + if (focusElement.getParentElement() == null) { + Style style = focusElement.getStyle(); + style.setPosition(Position.FIXED); + style.setTop(0, Unit.PX); + style.setLeft(0, Unit.PX); + getElement().appendChild(focusElement); + /* Sink from focusElement too as focus and blur don't bubble */ + DOM.sinkEvents( + (com.google.gwt.user.client.Element) focusElement + .cast(), Event.FOCUSEVENTS); + // revert to original, not focusable + getElement().setPropertyObject("tabIndex", null); + } else { + moveFocusElementAfterWidget(); + } + } + } + + /** + * Helper to keep focus element always in domChild[1]. Aids testing. + */ + private void moveFocusElementAfterWidget() { + getElement().insertAfter(focusElement, getWidget().getElement()); + } + + @Override + public void setFocus(boolean focus) { + if (BrowserInfo.get().isIE6()) { + super.setFocus(focus); + } else { + if (focus) { + FocusImpl.getFocusImplForPanel().focus( + (Element) focusElement.cast()); + } else { + FocusImpl.getFocusImplForPanel().blur( + (Element) focusElement.cast()); + } + } + } + + @Override + public void setTabIndex(int tabIndex) { + if (BrowserInfo.get().isIE6()) { + super.setTabIndex(tabIndex); + } else { + getElement().setTabIndex(-1); + if (focusElement != null) { + focusElement.setTabIndex(tabIndex); + } + } + } +} diff --git a/src/com/vaadin/terminal/gwt/client/ui/VTree.java b/src/com/vaadin/terminal/gwt/client/ui/VTree.java index 0ee86da0a0..53ca56aca9 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VTree.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VTree.java @@ -56,7 +56,7 @@ import com.vaadin.terminal.gwt.client.ui.dd.VerticalDropLocation; /** * */ -public class VTree extends SimpleFocusablePanel implements Paintable, +public class VTree extends FocusElementPanel implements Paintable, VHasDropHandler, FocusHandler, BlurHandler, KeyPressHandler, KeyDownHandler, SubPartAware, ActionOwner { @@ -152,6 +152,13 @@ public class VTree extends SimpleFocusablePanel implements Paintable, * selection patch in IE */ sinkEvents(Event.ONMOUSEDOWN | Event.ONMOUSEUP | Event.ONKEYUP); + + /* + * Re-set the tab index to make sure that the FocusElementPanel's + * (super) focus element gets the tab index and not the element + * containing the tree. + */ + setTabIndex(0); } /* @@ -628,6 +635,10 @@ public class VTree extends SimpleFocusablePanel implements Paintable, } } + private boolean isIE6OrOpera() { + return BrowserInfo.get().isIE6() || BrowserInfo.get().isOpera(); + } + /** * Handles mouse selection * @@ -643,6 +654,15 @@ public class VTree extends SimpleFocusablePanel implements Paintable, // always when clicking an item, focus it setFocusedNode(this, false); + if (!isIE6OrOpera()) { + /* + * Ensure that the tree's focus element also gains focus + * (TreeNodes focus is faked using FocusElementPanel in browsers + * other than IE6 and Opera). + */ + focus(); + } + ScheduledCommand command = new ScheduledCommand() { public void execute() { @@ -810,10 +830,14 @@ public class VTree extends SimpleFocusablePanel implements Paintable, * previously modified field may contain dirty variables. */ if (!treeHasFocus) { - if (focusedNode == null) { - getNodeByKey(key).setFocused(true); + if (isIE6OrOpera()) { + if (focusedNode == null) { + getNodeByKey(key).setFocused(true); + } else { + focusedNode.setFocused(true); + } } else { - focusedNode.setFocused(true); + focus(); } } final MouseEventDetails details = new MouseEventDetails(evt); @@ -870,11 +894,13 @@ public class VTree extends SimpleFocusablePanel implements Paintable, DOM.appendChild(nodeCaptionDiv, wrapper); DOM.appendChild(wrapper, nodeCaptionSpan); - /* - * Focus the caption div of the node to get keyboard navigation to - * work without scrolling up or down when focusing a node. - */ - nodeCaptionDiv.setTabIndex(-1); + if (isIE6OrOpera()) { + /* + * Focus the caption div of the node to get keyboard navigation + * to work without scrolling up or down when focusing a node. + */ + nodeCaptionDiv.setTabIndex(-1); + } childNodeContainer = new FlowPanel(); childNodeContainer.setStyleName(CLASSNAME + "-children"); @@ -1167,7 +1193,9 @@ public class VTree extends SimpleFocusablePanel implements Paintable, ie6compatnode.addClassName(CLASSNAME_FOCUSED); } this.focused = focused; - nodeCaptionDiv.focus(); + if (isIE6OrOpera()) { + nodeCaptionDiv.focus(); + } treeHasFocus = true; } else if (this.focused && !focused) { nodeCaptionDiv.removeClassName(CLASSNAME_FOCUSED); @@ -1776,9 +1804,10 @@ public class VTree extends SimpleFocusablePanel implements Paintable, focusedNode); setFocusedNode(focusedNode.getParentNode()); } else { - setSelected(focusedNode, false); + TreeNode oldFocusedNode = focusedNode; setFocusedNode(focusedNode.getParentNode()); setSelected(focusedNode, true); + setSelected(oldFocusedNode, false); } } return true; @@ -1796,9 +1825,10 @@ public class VTree extends SimpleFocusablePanel implements Paintable, setFocusedNode(focusedNode.getChildren().get(0)); setSelected(focusedNode, true); } else { - setSelected(focusedNode, false); + TreeNode oldFocusedNode = focusedNode; setFocusedNode(focusedNode.getChildren().get(0)); setSelected(focusedNode, true); + setSelected(oldFocusedNode, false); } } return true; |