瀏覽代碼

Displaying tooltip in slot for touch devices (#15353)

Change-Id: Ia2fce4dbfc205b44622557017afff19c4a2ef7df
tags/7.5.0.alpha1
Alexey Fansky 9 年之前
父節點
當前提交
05fc5806e7

+ 23
- 13
client/src/com/vaadin/client/VTooltip.java 查看文件

@@ -20,17 +20,7 @@ import com.google.gwt.aria.client.RelevantValue;
import com.google.gwt.aria.client.Roles;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Style.Display;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.DomEvent;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.dom.client.MouseMoveEvent;
import com.google.gwt.event.dom.client.MouseMoveHandler;
import com.google.gwt.event.dom.client.*;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Timer;
@@ -388,7 +378,8 @@ public class VTooltip extends VOverlay {
}

private class TooltipEventHandler implements MouseMoveHandler,
KeyDownHandler, FocusHandler, BlurHandler, MouseDownHandler {
KeyDownHandler, FocusHandler, BlurHandler, MouseDownHandler,
MouseUpHandler, TouchStartHandler {

/**
* Current element hovered
@@ -400,6 +391,11 @@ public class VTooltip extends VOverlay {
*/
private boolean handledByFocus;

/**
* Indicates whether the tooltip is being called after a touch event.
*/
private boolean touchInitiated = false;

/**
* Locate the tooltip for given element
*
@@ -450,7 +446,19 @@ public class VTooltip extends VOverlay {

@Override
public void onMouseMove(MouseMoveEvent mme) {
handleShowHide(mme, false);
if (!touchInitiated) {
handleShowHide(mme, false);
}
}

@Override
public void onMouseUp(MouseUpEvent event) {
touchInitiated = false;
}

@Override
public void onTouchStart(TouchStartEvent te) {
touchInitiated = true;
}

@Override
@@ -550,9 +558,11 @@ public class VTooltip extends VOverlay {
Profiler.enter("VTooltip.connectHandlersToWidget");
widget.addDomHandler(tooltipEventHandler, MouseMoveEvent.getType());
widget.addDomHandler(tooltipEventHandler, MouseDownEvent.getType());
widget.addDomHandler(tooltipEventHandler, MouseUpEvent.getType());
widget.addDomHandler(tooltipEventHandler, KeyDownEvent.getType());
widget.addDomHandler(tooltipEventHandler, FocusEvent.getType());
widget.addDomHandler(tooltipEventHandler, BlurEvent.getType());
widget.addDomHandler(tooltipEventHandler, TouchStartEvent.getType());
Profiler.leave("VTooltip.connectHandlersToWidget");
}


+ 102
- 6
client/src/com/vaadin/client/ui/orderedlayout/Slot.java 查看文件

@@ -22,9 +22,12 @@ import com.google.gwt.aria.client.Roles;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Timer;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.*;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.vaadin.client.BrowserInfo;
@@ -44,6 +47,7 @@ import com.vaadin.shared.ui.AlignmentInfo;
public final class Slot extends SimplePanel {

private static final String ALIGN_CLASS_PREFIX = "v-align-";
private static final int TOUCH_ERROR_MESSAGE_HIDE_DELAY = 200;

private final VAbstractOrderedLayout layout;

@@ -55,8 +59,13 @@ public final class Slot extends SimplePanel {
private Element captionText;
private Icon icon;
private Element errorIcon;
private Element errorMessage;
private Element requiredIcon;

private HandlerRegistration focusRegistration;
private HandlerRegistration blurRegistration;
private boolean labelClicked = false;

private ElementResizeListener captionResizeListener;

private ElementResizeListener widgetResizeListener;
@@ -582,9 +591,21 @@ public final class Slot extends SimplePanel {
errorIcon.setClassName("v-errorindicator");
}
caption.appendChild(errorIcon);
} else if (errorIcon != null) {
errorIcon.removeFromParent();
errorIcon = null;

if(BrowserInfo.get().isTouchDevice()) {
addFocusHandlerToWidget(error, widget);
addBlurHandlerToWidget(widget);
}

} else {
if (errorIcon != null) {
errorIcon.removeFromParent();
errorIcon = null;
}

if (errorMessage != null) {
removeErrorMessageAndHandlers();
}
}

if (caption != null) {
@@ -651,6 +672,81 @@ public final class Slot extends SimplePanel {
}
}

private void removeErrorMessageAndHandlers() {
errorMessage.removeFromParent();
errorMessage = null;

if (focusRegistration != null) {
focusRegistration.removeHandler();
focusRegistration = null;
}

if(blurRegistration != null) {
blurRegistration.removeHandler();
blurRegistration = null;
}
}

private void addFocusHandlerToWidget(final String error, Widget widget) {
focusRegistration = widget.addHandler(new FocusHandler() {
@Override
public void onFocus(FocusEvent event) {
if(labelClicked) {
labelClicked = false;
return;
}
if (errorMessage == null) {
errorMessage = DOM.createDiv();
errorMessage.setClassName("v-touch-error-message");
}
errorMessage.setInnerHTML(error);
captionWrap.appendChild(errorMessage);
}
}, FocusEvent.getType());
}

private void addBlurHandlerToWidget(final Widget widget) {
blurRegistration = widget.addHandler(new BlurHandler() {
@Override
public void onBlur(BlurEvent event) {
if(errorMessage != null) {
addClickHandlerToErrorMessage(widget);
}
scheduleErrorMessageHide(TOUCH_ERROR_MESSAGE_HIDE_DELAY);
}
}, BlurEvent.getType());
}

private void scheduleErrorMessageHide(int delay) {
//Delaying hiding to allow error message click handler
//do his job and return the focus back if error message was tapped
Timer hideTimer = new Timer() {
@Override
public void run() {
if(errorMessage != null) {
errorMessage.removeFromParent();
errorMessage = null;
}
}
};
hideTimer.schedule(delay);
}

private void addClickHandlerToErrorMessage(final Widget widget) {
Event.sinkEvents(errorMessage, Event.ONCLICK);
Event.setEventListener(errorMessage, new EventListener() {
@Override
public void onBrowserEvent(Event event) {
if(Event.ONCLICK == event.getTypeInt()) {
errorMessage.removeFromParent();
errorMessage = null;
labelClicked = true;
widget.getElement().focus();
}
}
});
}

/**
* Does the slot have a caption
*/

+ 57
- 0
uitest/src/com/vaadin/tests/components/TouchDevicesTooltip.java 查看文件

@@ -0,0 +1,57 @@
package com.vaadin.tests.components;

import com.vaadin.data.util.converter.StringToIntegerConverter;
import com.vaadin.data.validator.IntegerRangeValidator;
import com.vaadin.server.VaadinRequest;
import com.vaadin.ui.Label;
import com.vaadin.ui.TextField;

import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;

public class TouchDevicesTooltip extends AbstractTestUI {

@Override
protected void setup(VaadinRequest request) {
final Label errorLabel = new Label("No error");
addComponent(errorLabel);

TextField textField = new TextField("Value");
textField.setConverter(new StringToIntegerConverter());
textField.addValidator(new IntegerRangeValidator("incorrect value", 0, 100));
textField.setImmediate(true);
textField.setValue("-5");
addComponent(textField);

TextField textField2 = new TextField("Value2");
textField2.setConverter(new StringToIntegerConverter());
textField2.addValidator(new IntegerRangeValidator("incorrect value2", 0, 100));
textField2.setImmediate(true);
textField2.setValue("-5");
addComponent(textField2);
}

public static class Bean {
@NotNull
@Min(0)
private Integer value;

public Integer getValue() {
return value;
}

public void setValue(Integer value) {
this.value = value;
}
}

@Override
protected Integer getTicketNumber() {
return 15353;
}

@Override
public String getDescription() {
return "Displaying error message in slot for touch devices";
}
}

Loading…
取消
儲存