/*
@VaadinAddonLicenseForJavaFiles@
*/
package com.spaceapplications.vaadin.addon.eventtimeline.gwt.client;
import com.google.gwt.dom.client.NativeEvent;
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.shared.HandlerRegistration;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Event.NativePreviewEvent;
import com.google.gwt.user.client.Event.NativePreviewHandler;
import com.google.gwt.user.client.ui.Widget;
/**
* VEventTimelineBand.
*
* @author Thomas Neidhart / Space Applications Services NV/SA
*/
public class VEventTimelineBand extends Widget implements MouseDownHandler,
MouseMoveHandler, MouseUpHandler, NativePreviewHandler {
private static final String CLASSNAME_BAND = VEventTimelineWidget.CLASSNAME + "-band";
private static final String CLASSNAME_BAND_SELECTED = CLASSNAME_BAND + "-selected";
private static final String CLASSNAME_BAND_LABEL = CLASSNAME_BAND + "-label";
private static final String CLASSNAME_BAND_ADJUSTER = "v-band-adjuster";
private final Element bandRoot;
private final Element bandLabel;
private final Element bandAdjuster;
private boolean mouseDown;
private boolean mouseIsActive = false;
private boolean sizeAdjust;
private int dragStartY;
private HandlerRegistration mouseMoveReg, mouseUpReg, mouseDownReg, preview;
private int bandId;
private VEventTimelineBandArea bandArea;
private boolean selected;
/**
* Create a new band.
*
* @param bandId the band id
* @param caption the caption
* @param bandArea the ui element representing the band
*/
public VEventTimelineBand(int bandId, final String caption, final VEventTimelineBandArea bandArea) {
this.bandId = bandId;
this.bandArea = bandArea;
bandRoot = DOM.createDiv();
setElement(bandRoot);
setStyleName(CLASSNAME_BAND);
bandLabel = DOM.createDiv();
bandLabel.setClassName(CLASSNAME_BAND_LABEL);
bandLabel.setInnerText(caption);
bandRoot.appendChild(bandLabel);
bandAdjuster = DOM.createDiv();
bandAdjuster.setClassName(CLASSNAME_BAND_ADJUSTER);
bandRoot.appendChild(bandAdjuster);
}
@Override
protected void onLoad() {
super.onLoad();
mouseDownReg = addDomHandler(this, MouseDownEvent.getType());
mouseUpReg = addDomHandler(this, MouseUpEvent.getType());
mouseMoveReg = addDomHandler(this, MouseMoveEvent.getType());
preview = Event.addNativePreviewHandler(this);
disableAdjuster();
}
@Override
protected void onUnload() {
super.onUnload();
if (mouseDownReg != null) {
mouseDownReg.removeHandler();
mouseDownReg = null;
}
if (mouseUpReg != null) {
mouseUpReg.removeHandler();
mouseUpReg = null;
}
if (mouseMoveReg != null) {
mouseMoveReg.removeHandler();
mouseMoveReg = null;
}
if (preview != null) {
preview.removeHandler();
preview = null;
}
}
@Override
public void setWidth(String width) {
super.setWidth(width);
updateBandAdjuster();
}
@Override
public void setHeight(String height) {
super.setHeight(height);
updateBandAdjuster();
}
public int getHeight() {
return DOM.getIntStyleAttribute(bandRoot, "height");
}
/**
* Returns true, if the band is selected.
*
* @return
*/
public boolean isSelected() {
return selected;
}
/**
* Pass true, to mark the band as selected and false to deselect a band.
*
* @param value
*/
public void setSelected(boolean selected) {
this.selected = selected;
applySelectionStyle();
}
/**
* Applies a style attribute based on the selection state.
*/
private void applySelectionStyle() {
if (selected) {
removeStyleName(CLASSNAME_BAND);
addStyleName(CLASSNAME_BAND_SELECTED);
} else {
removeStyleName(CLASSNAME_BAND_SELECTED);
addStyleName(CLASSNAME_BAND);
}
}
/**
* Returns the id of that band.
*
* @return the bandId
*/
public int getId() {
return bandId;
}
public void updateBandAdjuster() {
int center = bandRoot.getOffsetWidth() / 2 - 8;
DOM.setStyleAttribute(bandAdjuster, "left", center + "px");
int bottom = bandRoot.getOffsetHeight() - bandLabel.getOffsetHeight() - 4;
DOM.setStyleAttribute(bandAdjuster, "top", bottom + "px");
}
public void enableAdjuster() {
DOM.setStyleAttribute(bandAdjuster, "visibility", "visible");
}
public void disableAdjuster() {
DOM.setStyleAttribute(bandAdjuster, "visibility", "hidden");
}
public boolean isMouseOverSizeAdjuster(Event mouseEvent) {
Element mouseOver = (Element) Element.as(mouseEvent.getEventTarget());
return mouseOver == bandAdjuster;
}
/**
* Checks if element exists in the browser
*
* @param elem
* The element
* @return True if the element exists, else false
*/
public boolean hasElement(com.google.gwt.dom.client.Element elem) {
if (elem == getElement() || elem == bandRoot || elem == bandLabel
|| elem == bandAdjuster) {
return true;
} else {
return false;
}
}
/*
* (non-Javadoc)
*
* @see
* com.google.gwt.event.dom.client.MouseUpHandler#onMouseUp(com.google.gwt
* .event.dom.client.MouseUpEvent)
*/
public void onMouseUp(MouseUpEvent event) {
mouseIsActive = false;
DOM.releaseCapture(bandRoot);
sizeAdjust = false;
// notify that the band was selected
bandArea.bandSelected(bandId);
// redraw
bandArea.redraw();
}
/*
* (non-Javadoc)
*
* @see
* com.google.gwt.event.dom.client.MouseMoveHandler#onMouseMove(com.google
* .gwt.event.dom.client.MouseMoveEvent)
*/
public void onMouseMove(MouseMoveEvent event) {
NativeEvent mouseEvent = event.getNativeEvent();
if (mouseDown) {
int adjustment = mouseEvent.getClientY() - dragStartY;
if (sizeAdjust) {
if (bandArea.requestResize(bandId, getHeight(), adjustment)) {
dragStartY = mouseEvent.getClientY();
}
}
}
}
/*
* (non-Javadoc)
*
* @see
* com.google.gwt.event.dom.client.MouseDownHandler#onMouseDown(com.google
* .gwt.event.dom.client.MouseDownEvent)
*/
public void onMouseDown(MouseDownEvent event) {
mouseIsActive = true;
NativeEvent mouseEvent = event.getNativeEvent();
event.preventDefault();
event.stopPropagation();
DOM.setCapture(bandRoot);
if (isMouseOverSizeAdjuster((Event) mouseEvent)) {
sizeAdjust = true;
dragStartY = mouseEvent.getClientY();
}
}
public void onPreviewNativeEvent(NativePreviewEvent event) {
// Monitor mouse button state
if (event.getTypeInt() == Event.ONMOUSEUP
&& event.getNativeEvent().getButton() == NativeEvent.BUTTON_LEFT) {
mouseDown = false;
if (mouseIsActive) {
onMouseUp(null);
}
} else if (event.getTypeInt() == Event.ONMOUSEDOWN
&& event.getNativeEvent().getButton() == NativeEvent.BUTTON_LEFT) {
mouseDown = true;
}
}
}