package org.vaadin.touchkit.gwt.client.ui;
import org.vaadin.touchkit.gwt.client.VTouchKitResources;
import com.google.gwt.dom.client.Element;
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.MouseUpEvent;
import com.google.gwt.event.dom.client.MouseUpHandler;
import com.google.gwt.event.dom.client.TouchEndEvent;
import com.google.gwt.event.dom.client.TouchEndHandler;
import com.google.gwt.event.dom.client.TouchMoveEvent;
import com.google.gwt.event.dom.client.TouchMoveHandler;
import com.google.gwt.event.dom.client.TouchStartEvent;
import com.google.gwt.event.dom.client.TouchStartHandler;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
public class FloatingIndexWidget extends SimplePanel {
private FlowPanel p = new FlowPanel();
private boolean capturing;
private void startDrag(int y) {
Event.setCapture(getElement());
capturing = true;
scrollTo(y);
}
public FloatingIndexWidget() {
add(p);
setStyleName(VTouchKitResources.INSTANCE.css().floatingIndex());
addDomHandler(new MouseMoveHandler() {
@Override
public void onMouseMove(MouseMoveEvent event) {
if (capturing) {
scrollTo(event.getClientY());
event.stopPropagation();
event.preventDefault();
}
}
}, MouseMoveEvent.getType());
addDomHandler(new TouchMoveHandler() {
@Override
public void onTouchMove(TouchMoveEvent event) {
if (capturing) {
scrollTo(event.getTouches().get(0).getClientY());
event.stopPropagation();
event.preventDefault();
}
}
}, TouchMoveEvent.getType());
addDomHandler(new TouchEndHandler() {
@Override
public void onTouchEnd(TouchEndEvent event) {
Event.releaseCapture(getElement());
event.stopPropagation();
event.preventDefault();
capturing = false;
}
}, TouchEndEvent.getType());
addDomHandler(new MouseUpHandler() {
@Override
public void onMouseUp(MouseUpEvent event) {
Event.releaseCapture(getElement());
event.stopPropagation();
event.preventDefault();
capturing = false;
}
}, MouseUpEvent.getType());
}
private void scrollTo(int y) {
Widget target = null;
for (Widget w : p) {
int absoluteTop = w.getAbsoluteTop();
if (absoluteTop < y) {
target = w;
} else {
break;
}
}
if (target != null) {
((Item) target).scrollToWidget();
}
}
public void map(String key, final Widget w,
final com.google.gwt.dom.client.Element element) {
Item label = new Item(key, w, element);
p.add(label);
}
private static native boolean isScrollable(
com.google.gwt.dom.client.Element e) throws Exception
/*-{
var overflow = $wnd.getComputedStyle(e).getPropertyValue("overflow");
if( overflow == 'auto' || overflow == 'scroll') {
return true;
} else {
return false;
}
}-*/;
class Item extends HTML {
private Element element;
private Widget w;
public Item(String key, final Widget w, final Element element) {
super("<div>" + key + "</div>");
this.w = w;
this.element = element;
addTouchStartHandler(new TouchStartHandler() {
@Override
public void onTouchStart(TouchStartEvent event) {
startDrag(event.getTouches().get(0).getClientY());
event.stopPropagation();
event.preventDefault();
}
});
addMouseDownHandler(new MouseDownHandler() {
@Override
public void onMouseDown(MouseDownEvent event) {
startDrag(event.getClientY());
event.stopPropagation();
event.preventDefault();
}
});
}
private void scrollToWidget() {
try {
com.google.gwt.dom.client.Element e;
if (element == null) {
e = w.getElement().getParentElement();
while (e != null && !isScrollable(e)) {
e = e.getParentElement();
}
} else {
e = element;
}
e.setScrollTop(e.getScrollHeight());
} catch (Exception e) {
}
// Sanity check
w.getElement().scrollIntoView();
}
}
}