From 3292a1ddd2d2787d152532383282237f28d99e28 Mon Sep 17 00:00:00 2001 From: John Alhroos Date: Wed, 2 Jun 2010 12:35:04 +0000 Subject: [PATCH] - Added keyboard navigation to Slider - SimpleFocusablePanel now implements Focusable so keyboard focus can also be set from the server side. svn changeset:13497/svn branch:6.4 --- .../gwt/client/ui/SimpleFocusablePanel.java | 7 +- .../terminal/gwt/client/ui/VSlider.java | 126 +++++++++++++++++- 2 files changed, 125 insertions(+), 8 deletions(-) diff --git a/src/com/vaadin/terminal/gwt/client/ui/SimpleFocusablePanel.java b/src/com/vaadin/terminal/gwt/client/ui/SimpleFocusablePanel.java index 967e60d466..b534e3faba 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/SimpleFocusablePanel.java +++ b/src/com/vaadin/terminal/gwt/client/ui/SimpleFocusablePanel.java @@ -15,6 +15,7 @@ import com.google.gwt.event.dom.client.KeyPressHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.ui.SimplePanel; import com.google.gwt.user.client.ui.impl.FocusImpl; +import com.vaadin.terminal.gwt.client.Focusable; /** * Compared to FocusPanel in GWT this panel does not support eg. accesskeys, but @@ -22,7 +23,7 @@ import com.google.gwt.user.client.ui.impl.FocusImpl; */ public class SimpleFocusablePanel extends SimplePanel implements HasFocusHandlers, HasBlurHandlers, HasKeyDownHandlers, - HasKeyPressHandlers { + HasKeyPressHandlers, Focusable { public SimpleFocusablePanel() { // make focusable, as we don't need access key magic we don't need to @@ -53,4 +54,8 @@ public class SimpleFocusablePanel extends SimplePanel implements FocusImpl.getFocusImplForPanel().blur(getElement()); } } + + public void focus() { + setFocus(true); + } } diff --git a/src/com/vaadin/terminal/gwt/client/ui/VSlider.java b/src/com/vaadin/terminal/gwt/client/ui/VSlider.java index 81fb898011..d30c2b2f20 100644 --- a/src/com/vaadin/terminal/gwt/client/ui/VSlider.java +++ b/src/com/vaadin/terminal/gwt/client/ui/VSlider.java @@ -4,6 +4,7 @@ // package com.vaadin.terminal.gwt.client.ui; +import com.google.gwt.event.dom.client.KeyCodes; import com.google.gwt.user.client.Command; import com.google.gwt.user.client.DOM; import com.google.gwt.user.client.DeferredCommand; @@ -12,14 +13,13 @@ import com.google.gwt.user.client.Event; import com.google.gwt.user.client.Timer; import com.google.gwt.user.client.Window; import com.google.gwt.user.client.ui.HTML; -import com.google.gwt.user.client.ui.Widget; import com.vaadin.terminal.gwt.client.ApplicationConnection; import com.vaadin.terminal.gwt.client.BrowserInfo; import com.vaadin.terminal.gwt.client.ContainerResizedListener; import com.vaadin.terminal.gwt.client.Paintable; import com.vaadin.terminal.gwt.client.UIDL; -public class VSlider extends Widget implements Paintable, Field, +public class VSlider extends SimpleFocusablePanel implements Paintable, Field, ContainerResizedListener { public static final String CLASSNAME = "v-slider"; @@ -39,6 +39,7 @@ public class VSlider extends Widget implements Paintable, Field, private boolean readonly; private boolean scrollbarStyle; + private int acceleration = 1; private int handleSize; private double min; private double max; @@ -76,7 +77,6 @@ public class VSlider extends Widget implements Paintable, Field, public VSlider() { super(); - setElement(DOM.createDiv()); base = DOM.createDiv(); handle = DOM.createDiv(); smaller = DOM.createDiv(); @@ -98,18 +98,19 @@ public class VSlider extends Widget implements Paintable, Field, DOM.setStyleAttribute(bigger, "display", "none"); DOM.setStyleAttribute(handle, "visibility", "hidden"); - DOM.sinkEvents(getElement(), Event.MOUSEEVENTS | Event.ONMOUSEWHEEL); + DOM.sinkEvents(getElement(), Event.MOUSEEVENTS | Event.ONMOUSEWHEEL + | Event.KEYEVENTS | Event.FOCUSEVENTS); DOM.sinkEvents(base, Event.ONCLICK); DOM.sinkEvents(handle, Event.MOUSEEVENTS); DOM.sinkEvents(smaller, Event.ONMOUSEDOWN | Event.ONMOUSEUP | Event.ONMOUSEOUT); DOM.sinkEvents(bigger, Event.ONMOUSEDOWN | Event.ONMOUSEUP | Event.ONMOUSEOUT); - + feedbackPopup.addStyleName(CLASSNAME + "-feedback"); feedbackPopup.setWidget(feedback); } - + public void updateFromUIDL(UIDL uidl, ApplicationConnection client) { this.client = client; @@ -332,8 +333,35 @@ public class VSlider extends Widget implements Paintable, Field, decreaseValue(true); } else if (targ == bigger) { increaseValue(true); - } else { + } else if (DOM.eventGetType(event) == Event.MOUSEEVENTS) { processBaseEvent(event); + } else if ((BrowserInfo.get().isGecko() && DOM.eventGetType(event) == Event.ONKEYPRESS) + || (!BrowserInfo.get().isGecko() && DOM.eventGetType(event) == Event.ONKEYDOWN)) { + + if (handleNavigation(event.getKeyCode(), event.getCtrlKey(), event + .getShiftKey())) { + + feedbackPopup.show(); + + if (scrollTimer != null) { + scrollTimer.cancel(); + } + scrollTimer = new Timer() { + @Override + public void run() { + updateValueToServer(); + acceleration = 1; + } + }; + scrollTimer.schedule(100); + + DOM.eventPreventDefault(event); + DOM.eventCancelBubble(event, true); + } + } else if (DOM.eventGetType(event) == Event.ONFOCUS) { + feedbackPopup.show(); + } else if (DOM.eventGetType(event) == Event.ONBLUR) { + feedbackPopup.hide(); } } @@ -478,4 +506,88 @@ public class VSlider extends Widget implements Paintable, Field, client.updateVariable(id, "value", value.doubleValue(), immediate); } + /** + * Handles the keyboard events handled by the Slider + * + * @param event + * The keyboard event received + * @return true iff the navigation event was handled + */ + public boolean handleNavigation(int keycode, boolean ctrl, boolean shift) { + + // No support for ctrl moving + if (ctrl) { + return false; + } + + if ((keycode == getNavigationUpKey() && vertical) + || (keycode == getNavigationRightKey() && !vertical)) { + if (shift) { + for (int a = 0; a < acceleration; a++) { + increaseValue(false); + } + acceleration++; + } else { + increaseValue(false); + } + return true; + } else if (keycode == getNavigationDownKey() && vertical + || (keycode == getNavigationLeftKey() && !vertical)) { + if (shift) { + for (int a = 0; a < acceleration; a++) { + decreaseValue(false); + } + acceleration++; + } else { + decreaseValue(false); + } + return true; + } + + return false; + } + + /** + * Get the key that increases the vertical slider. By default it is the up + * arrow key but by overriding this you can change the key to whatever you + * want. + * + * @return The keycode of the key + */ + protected int getNavigationUpKey() { + return KeyCodes.KEY_UP; + } + + /** + * Get the key that decreases the vertical slider. By default it is the down + * arrow key but by overriding this you can change the key to whatever you + * want. + * + * @return The keycode of the key + */ + protected int getNavigationDownKey() { + return KeyCodes.KEY_DOWN; + } + + /** + * Get the key that decreases the horizontal slider. By default it is the + * left arrow key but by overriding this you can change the key to whatever + * you want. + * + * @return The keycode of the key + */ + protected int getNavigationLeftKey() { + return KeyCodes.KEY_LEFT; + } + + /** + * Get the key that increases the horizontal slider. By default it is the + * right arrow key but by overriding this you can change the key to whatever + * you want. + * + * @return The keycode of the key + */ + protected int getNavigationRightKey() { + return KeyCodes.KEY_RIGHT; + } } -- 2.39.5