* Clicking on slider makes handler move Fixes #1496 * Introducing control over clicking behaviour - User will have to enable process of the click event on handle calling `slider.setEnableClickHandler(true);` - Clean-up the handler logic in VSlider.java - Renaming the property to `updateValueOnClick` - Added JavaDocs - Fixing teststags/8.8.0.beta1
protected double max; | protected double max; | ||||
protected int resolution; | protected int resolution; | ||||
protected Double value; | protected Double value; | ||||
private boolean updateValueOnClick; | |||||
protected SliderOrientation orientation = SliderOrientation.HORIZONTAL; | protected SliderOrientation orientation = SliderOrientation.HORIZONTAL; | ||||
private final HTML feedback = new HTML("", false); | private final HTML feedback = new HTML("", false); | ||||
processMouseWheelEvent(event); | processMouseWheelEvent(event); | ||||
} else if (dragging || targ == handle) { | } else if (dragging || targ == handle) { | ||||
processHandleEvent(event); | processHandleEvent(event); | ||||
} else if (targ.equals(base) | |||||
&& DOM.eventGetType(event) == Event.ONMOUSEUP | |||||
&& updateValueOnClick) { | |||||
processBaseEvent(event); | |||||
feedbackPopup.show(); | |||||
} else if (targ == smaller) { | } else if (targ == smaller) { | ||||
decreaseValue(true); | decreaseValue(true); | ||||
} else if (targ == bigger) { | } else if (targ == bigger) { | ||||
increaseValue(true); | increaseValue(true); | ||||
} else if (DOM.eventGetType(event) == Event.MOUSEEVENTS) { | |||||
processBaseEvent(event); | |||||
} else if (isNavigationEvent(event)) { | } else if (isNavigationEvent(event)) { | ||||
if (handleNavigation(event.getKeyCode(), event.getCtrlKey(), | if (handleNavigation(event.getKeyCode(), event.getCtrlKey(), | ||||
} | } | ||||
private boolean isNavigationEvent(Event event) { | private boolean isNavigationEvent(Event event) { | ||||
if (BrowserInfo.get().isGecko() && BrowserInfo.get().getGeckoVersion() < 65) { | |||||
if (BrowserInfo.get().isGecko() | |||||
&& BrowserInfo.get().getGeckoVersion() < 65) { | |||||
return DOM.eventGetType(event) == Event.ONKEYPRESS; | return DOM.eventGetType(event) == Event.ONKEYPRESS; | ||||
} else { | } else { | ||||
return DOM.eventGetType(event) == Event.ONKEYDOWN; | return DOM.eventGetType(event) == Event.ONKEYDOWN; | ||||
} | } | ||||
private void processBaseEvent(Event event) { | private void processBaseEvent(Event event) { | ||||
if (DOM.eventGetType(event) == Event.ONMOUSEDOWN) { | |||||
if (!disabled && !readonly && !dragging) { | |||||
setValueByEvent(event, true); | |||||
DOM.eventCancelBubble(event, true); | |||||
} | |||||
if (!disabled && !readonly && !dragging) { | |||||
setValueByEvent(event, true); | |||||
DOM.eventCancelBubble(event, true); | |||||
} | } | ||||
} | } | ||||
} | } | ||||
return null; | return null; | ||||
} | } | ||||
/** | |||||
* Specifies whether or not click event should update the Slider's value. | |||||
* | |||||
* @param updateValueOnClick | |||||
*/ | |||||
public void setUpdateValueOnClick(boolean updateValueOnClick) { | |||||
this.updateValueOnClick = updateValueOnClick; | |||||
} | |||||
} | } |
getWidget().setMaxValue(getState().maxValue); | getWidget().setMaxValue(getState().maxValue); | ||||
getWidget().setResolution(getState().resolution); | getWidget().setResolution(getState().resolution); | ||||
getWidget().setValue(getState().value, false); | getWidget().setValue(getState().value, false); | ||||
getWidget().setUpdateValueOnClick(getState().updateValueOnClick); | |||||
getWidget().buildBase(); | getWidget().buildBase(); | ||||
getWidget().setTabIndex(getState().tabIndex); | getWidget().setTabIndex(getState().tabIndex); |
getState().resolution = resolution; | getState().resolution = resolution; | ||||
} | } | ||||
/** | |||||
* Sets the slider to update its value when the user clicks on it. | |||||
* By default, the slider value is updated by dragging the slider's handle | |||||
* or clicking arrows. | |||||
* | |||||
* @param updateValueOnClick | |||||
* {@code true} to update the value of the slider on click, | |||||
* {@code false} otherwise. | |||||
* @since | |||||
*/ | |||||
public void setUpdateValueOnClick(boolean updateValueOnClick) { | |||||
getState().updateValueOnClick = updateValueOnClick; | |||||
} | |||||
/** | |||||
* Returns whether the slider updates its value on user click. | |||||
* | |||||
* @return {@code true} if the Slider updates its value on click. By | |||||
* default, returns {@code false} | |||||
* @since | |||||
*/ | |||||
public boolean isUpdateValueOnClick() { | |||||
return getState(false).updateValueOnClick; | |||||
} | |||||
private double getRoundedValue(Double value) { | private double getRoundedValue(Double value) { | ||||
final double v = value.doubleValue(); | final double v = value.doubleValue(); | ||||
final int resolution = getResolution(); | final int resolution = getResolution(); |
@NoLayout | @NoLayout | ||||
public int resolution = 0; | public int resolution = 0; | ||||
@NoLayout | |||||
public boolean updateValueOnClick = false; | |||||
public SliderOrientation orientation = SliderOrientation.HORIZONTAL; | public SliderOrientation orientation = SliderOrientation.HORIZONTAL; | ||||
} | } |
package com.vaadin.tests.components.slider; | |||||
import com.vaadin.annotations.Widgetset; | |||||
import com.vaadin.server.VaadinRequest; | |||||
import com.vaadin.tests.components.AbstractTestUI; | |||||
import com.vaadin.ui.Slider; | |||||
import com.vaadin.ui.Button; | |||||
@Widgetset("com.vaadin.DefaultWidgetSet") | |||||
public class SliderHandleBaseClick extends AbstractTestUI { | |||||
@Override | |||||
protected void setup(VaadinRequest request) { | |||||
Slider slider = new Slider(); | |||||
slider.setWidth(500, Unit.PIXELS); | |||||
slider.setMin(0); | |||||
slider.setMax(10); | |||||
slider.setValue(3.0); | |||||
slider.setUpdateValueOnClick(true); | |||||
addComponent(slider); | |||||
Button toggleHandling = new Button("Apply/remove click action", e -> { | |||||
slider.setUpdateValueOnClick(!slider.isUpdateValueOnClick()); | |||||
}); | |||||
toggleHandling.setId("toggleHandling"); | |||||
addComponent(toggleHandling); | |||||
} | |||||
@Override | |||||
protected String getTestDescription() { | |||||
return "Slider should update its value, when clicked on the base"; | |||||
} | |||||
@Override | |||||
protected Integer getTicketNumber() { | |||||
return 1496; | |||||
} | |||||
} |
package com.vaadin.tests.components.slider; | |||||
import com.vaadin.tests.tb3.MultiBrowserTest; | |||||
import org.junit.Before; | |||||
import org.junit.Test; | |||||
import org.openqa.selenium.By; | |||||
import org.openqa.selenium.WebElement; | |||||
import org.openqa.selenium.interactions.Actions; | |||||
import static org.junit.Assert.assertEquals; | |||||
public class SliderHandleBaseClickTest extends MultiBrowserTest { | |||||
private WebElement base; | |||||
private int offsetStep; | |||||
@Before | |||||
public void setUp() throws Exception { | |||||
super.setup(); | |||||
openTestURL(); | |||||
base = findElement(By.className("v-slider-base")); | |||||
offsetStep = base.getSize().getWidth() / 10; | |||||
} | |||||
@Test | |||||
public void testHandlerHasMoved() { | |||||
// dragAndDropBy function starts calculating click position from the | |||||
// middle of the component . | |||||
// So the click will always be at the position (center + offsetStep)px | |||||
// Will move by one from the middle | |||||
new Actions(driver).dragAndDropBy(base, offsetStep, 0).perform(); | |||||
sleep(100); | |||||
assertEquals("The Slider value should be 6 after moving by one offset", | |||||
6, getSliderValue(), 0); | |||||
// Will move by two from the middle, in this case from 5 | |||||
new Actions(driver).dragAndDropBy(base, offsetStep * 2, 0).perform(); | |||||
sleep(100); | |||||
assertEquals("The Slider value should be 7 after moving by two offsets", | |||||
7, getSliderValue(), 0); | |||||
} | |||||
private double getSliderValue() { | |||||
return Double.valueOf( | |||||
findElement(By.className("v-slider-feedback")).getText()); | |||||
} | |||||
@Test | |||||
public void testHandlerNotMoved() { | |||||
// Disable click event handling | |||||
findElement(By.id("toggleHandling")).click(); | |||||
new Actions(driver).dragAndDropBy(base, offsetStep, 0).perform(); | |||||
sleep(100); | |||||
assertEquals(String.format( | |||||
"Slider value should not have changed. Expected 3.0 , but was %f", | |||||
getSliderValue()), 3.0,getSliderValue(), 0.0); | |||||
// Enable click event handling | |||||
findElement(By.id("toggleHandling")).click(); | |||||
} | |||||
} |