/* * Ext GWT - Ext for GWT * Copyright(c) 2007-2009, Ext JS, LLC. * licensing@extjs.com * * http://extjs.com/license */ package com.extjs.gxt.ui.client.aria; import java.util.ArrayList; import java.util.List; import com.extjs.gxt.ui.client.core.El; import com.extjs.gxt.ui.client.event.PreviewEvent; import com.extjs.gxt.ui.client.widget.Component; import com.extjs.gxt.ui.client.widget.ComponentManager; import com.extjs.gxt.ui.client.widget.Container; import com.extjs.gxt.ui.client.widget.ContentPanel; import com.extjs.gxt.ui.client.widget.LayoutContainer; import com.extjs.gxt.ui.client.widget.TabItem; import com.google.gwt.user.client.ui.ComplexPanel; import com.google.gwt.user.client.ui.HasWidgets; import com.google.gwt.user.client.ui.Panel; import com.google.gwt.user.client.ui.Widget; public abstract class FocusHandler { protected static boolean managed; public static boolean isManaged() { return FocusManager.get().isManaged(); } public abstract boolean canHandleKeyPress(Component component, PreviewEvent pe); public void onEnter(Component component, PreviewEvent pe) { } public void onEscape(Component component, PreviewEvent pe) { if (!isManaged()) return; stepOut(component); } public void onLeft(Component component, PreviewEvent pe) { } public void onRight(Component component, PreviewEvent pe) { } public void onTab(Component component, PreviewEvent pe) { } protected NavigationHandler findNavigationHandler(Component comp) { return FocusManager.get().findNavigationHandler(comp); } @SuppressWarnings("unchecked") protected void focusNextWidget(Widget c) { if (c instanceof Component) { Component comp = (Component) c; if (comp.getData("aria-next") != null) { String id = comp.getData("aria-next"); Component p = ComponentManager.get().get(id); if (p != null) { focusWidget(p); return; } } } Widget p = c.getParent(); NavigationHandler handler = findNavigationHandler((Component) p); if (handler != null) { List<Widget> widgets = handler.getOrderedWidgets(p); int idx = widgets.indexOf(c); if (idx != -1) { if (idx == widgets.size() - 1 && widgets.size() > 1) { focusWidget(widgets.get(0)); return; } else if (idx != widgets.size() - 1) { focusWidget(widgets.get(idx + 1)); return; } } } if (p instanceof Container) { Container con = (Container) p; int index = con.indexOf((Component) c) + 1; if (index == con.getItemCount()) { index = 0; } focusWidget(con.getItem(index)); } else if (p instanceof ComplexPanel) { ComplexPanel panel = (ComplexPanel) p; int index = panel.getWidgetIndex(c); if (index != -1) { if (index == panel.getWidgetCount() + 1) { index = 0; } else { ++index; } Widget w = panel.getWidget(index); focusWidget(w); } } } @SuppressWarnings("unchecked") protected void focusPreviousWidget(Widget c) { if (c instanceof Component) { Component comp = (Component) c; if (comp.getData("aria-previous") != null) { String id = comp.getData("aria-previous"); Component p = ComponentManager.get().get(id); if (p != null) { focusWidget(p); return; } } } Widget p = c.getParent(); List<Widget> widgets = null; NavigationHandler handler = findNavigationHandler((Component) p); if (handler != null) { widgets = handler.getOrderedWidgets(p); } else if (p instanceof Container) { Container con = (Container) p; widgets = con.getItems(); } else if (p instanceof HasWidgets) { HasWidgets hs = (HasWidgets) p; widgets = new ArrayList<Widget>(); while (hs.iterator().hasNext()) { widgets.add(hs.iterator().next()); } } int size = widgets.size(); int idx = widgets.indexOf(c); if (idx != -1) { if (idx > 0) { focusWidget(widgets.get(idx - 1), true); return; } else if (idx != 0 && size > 1) { focusWidget(widgets.get(size - 1), true); return; } else if (idx == 0 && size > 1) { focusWidget(widgets.get(size - 1), true); return; } } } protected void focusWidget(Widget w) { focusWidget(w, true); } protected void focusWidget(Widget w, boolean forward) { if (w instanceof Component) { Component c = (Component) w; if (c.isAriaIgnore()) { if (isContainer(c)) { stepInto(c, null, forward); } else { if (forward) { focusNextWidget(c); } else { focusPreviousWidget(c); } } } else { c.focus(); } } else { El.fly(w.getElement()).focus(); } } protected boolean isContainer(Widget w) { if (w instanceof LayoutContainer || w instanceof Panel) { return true; } return false; } protected void stepInto(Widget w, PreviewEvent pe, boolean forward) { if (w instanceof ContentPanel) { ContentPanel panel = (ContentPanel) w; if (panel.getTopComponent() != null) { focusWidget(panel.getTopComponent()); return; } } if (w instanceof LayoutContainer) { if (pe != null) pe.stopEvent(); LayoutContainer c = (LayoutContainer) w; if (c.getItemCount() > 0) { focusWidget(forward ? c.getItem(0) : c.getItem(c.getItemCount() - 1)); } } else if (w instanceof ComplexPanel) { if (pe != null) pe.stopEvent(); ComplexPanel panel = (ComplexPanel) w; if (panel.getWidgetCount() > 0) { focusWidget(panel.getWidget(0)); } } } protected void stepOut(Widget w) { Widget p = w.getParent(); if (p != null) { if (p instanceof TabItem) { ((TabItem) p).getTabPanel().focus(); } else if (p instanceof Component) { Component c = (Component) p; while (c.isAriaIgnore()) { p = c.getParent(); if (p instanceof Component) { c = (Component) p; } else { El.fly(p.getElement()).focus(); return; } } focusWidget(c); } else { El.fly(p.getElement()).focus(); FocusFrame.get().unframe(); } } } }