Java tutorial
/* @VaadinAddonLicenseForJavaFiles@ */ package com.spaceapplications.vaadin.addon.eventtimeline.gwt.client; import java.util.ArrayList; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; import com.google.gwt.core.client.GWT; 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.dom.client.MouseWheelEvent; import com.google.gwt.event.dom.client.MouseWheelHandler; import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.i18n.client.DateTimeFormat; import com.google.gwt.user.client.Command; 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.AbsolutePanel; import com.google.gwt.user.client.ui.HTML; import com.google.gwt.user.client.ui.Label; import com.google.gwt.user.client.ui.Widget; import com.spaceapplications.vaadin.addon.eventtimeline.gwt.canvas.client.Canvas; import com.spaceapplications.vaadin.addon.eventtimeline.gwt.style.client.ComputedStyle; import com.vaadin.terminal.gwt.client.DateTimeService; /** * VEventTimelineDisplay, based on original version from vaadin-timeline. * * @author Thomas Neidhart / Space Applications Services NV/SA * @author John Ahlroos / IT Mill Oy Ltd */ public class VEventTimelineDisplay extends Widget implements VDataListener, MouseDownHandler, MouseUpHandler, MouseMoveHandler, MouseWheelHandler, NativePreviewHandler { private static final String CLASSNAME_BOTTOMBAR = VEventTimelineWidget.DISPLAY_CLASSNAME + "-bottombar"; private static final String CLASSNAME_CANVAS = VEventTimelineWidget.DISPLAY_CLASSNAME + "-canvas"; private static final String CLASSNAME_CANVASDRAG = CLASSNAME_CANVAS + "-drag"; private static final String CLASSNAME_LOADINGCURTAIN = VEventTimelineWidget.DISPLAY_CLASSNAME + "-curtain"; public static final String CLASSNAME_EVENT = VEventTimelineWidget.CLASSNAME + "-event"; public static final String CLASSNAME_EVENT_SELECTED = CLASSNAME_EVENT + "-selected"; public static final String CLASSNAME_EVENT_CAPTION = CLASSNAME_EVENT + "-caption"; public static final String CLASSNAME_EVENT_CONTENT = CLASSNAME_EVENT + "-content"; private static final String CLASSNAME_SCALEVALUE = VEventTimelineWidget.DISPLAY_CLASSNAME + "-vscale"; private static final String CLASSNAME_SCALEVALUEDRAG = CLASSNAME_SCALEVALUE + "-drag"; private static final String CLASSNAME_SCALEDATE = VEventTimelineWidget.DISPLAY_CLASSNAME + "-hscale"; private static final String CLASSNAME_SCALEDATE_LEFT = CLASSNAME_SCALEDATE + "-left"; public static final Long SECOND = 1000L; public static final Long MINUTE = 60000L; public static final Long HOUR = 3600000L; public static final Long DAY = 86400000L; public static final Long WEEK = 604800000L; public static final Long MONTH = 2629743830L; public static final Long YEAR = 31556926000L; private final VEventTimelineWidget widget; private final Element browserRoot; private final AbsolutePanel displayComponentPanel; private final Canvas canvas; private final HTML bottomBar; private final Map<Integer, List<VEvent>> currentEvents = new TreeMap<Integer, List<VEvent>>(); private final List<VEventLabel> events = new ArrayList<VEventLabel>(); private Map<Integer, Integer> maxSlots = new HashMap<Integer, Integer>(); // The selected date range private Date currentStartDate = null; private Date currentEndDate = null; // Mouse actions private boolean mouseIsDown = false; private boolean mouseIsActive = false; private int mouseDownX = 0; private int lastMouseX = 0; // States private boolean enabled = true; private boolean forcePlot = false; // Dragging private Date currentStartDragDate = null; private Date currentEndDragDate = null; // Curtains private final HTML loadingCurtain; private final HTML disabledCurtain; // Scale components lists private final List<Label> horizontalScaleComponents = new ArrayList<Label>(); private final List<Label> verticalScaleComponents = new ArrayList<Label>(); // Error and loading messages private final Label noDataLabel = new Label("No data source."); // Graph formatting private String gridColor = "rgb(200,200,200)"; private HandlerRegistration mouseMoveReg, mouseUpReg, mouseDownReg, mouseScrollReg, preview; private DateTimeFormat yearFormatShort = DateTimeFormat.getFormat("''yy"); private DateTimeFormat yearFormatLong = DateTimeFormat.getFormat("yyyy"); private DateTimeFormat monthFormatShort = DateTimeFormat.getFormat("MMM yyyy"); private DateTimeFormat monthFormatLong = DateTimeFormat.getFormat("MMMM yyyy"); private DateTimeFormat dayFormatShort = DateTimeFormat.getFormat("MMM d, yyyy"); private DateTimeFormat dayFormatLong = DateTimeFormat.getFormat("MMMM d, yyyy"); private DateTimeFormat timeFormatShort = DateTimeFormat.getFormat("HH:mm"); private DateTimeFormat timeFormatLong = DateTimeFormat.getFormat("HH:mm:ss"); public VEventTimelineDisplay(VEventTimelineWidget w) { widget = w; browserRoot = DOM.createDiv(); setElement(browserRoot); setStyleName(VEventTimelineWidget.DISPLAY_CLASSNAME); // Add the components displayComponentPanel = new AbsolutePanel(); browserRoot.appendChild(displayComponentPanel.getElement()); DOM.setStyleAttribute(displayComponentPanel.getElement(), "position", "relative"); // Add the canvas canvas = new Canvas(100, 100); canvas.setStyleName(CLASSNAME_CANVAS); displayComponentPanel.add(canvas, 0, 0); // Create the loading indicator loadingCurtain = new HTML(""); loadingCurtain.setStyleName("v-app-loading"); loadingCurtain.addStyleName(CLASSNAME_LOADINGCURTAIN); loadingCurtain.setWidth("100%"); loadingCurtain.setHeight("100%"); displayComponentPanel.add(loadingCurtain); // Create the bottom bar bottomBar = new HTML(); bottomBar.setWidth("100%"); bottomBar.setStyleName(CLASSNAME_BOTTOMBAR); displayComponentPanel.add(bottomBar); // Add no data source label noDataLabel.setVisible(false); displayComponentPanel.add(noDataLabel, 10, 10); // Create the disabled curtain disabledCurtain = new HTML(""); disabledCurtain.setVisible(false); disabledCurtain.setStyleName(CLASSNAME_LOADINGCURTAIN); disabledCurtain.setWidth("100%"); disabledCurtain.setHeight("100%"); displayComponentPanel.add(disabledCurtain); } @Override protected void onLoad() { super.onLoad(); mouseDownReg = addDomHandler(this, MouseDownEvent.getType()); mouseUpReg = addDomHandler(this, MouseUpEvent.getType()); mouseMoveReg = addDomHandler(this, MouseMoveEvent.getType()); mouseScrollReg = addDomHandler(this, MouseWheelEvent.getType()); preview = Event.addNativePreviewHandler(this); } @Override public void setHeight(String height) { super.setHeight(height); int canvasHeight = getOffsetHeight() - bottomBar.getOffsetHeight(); canvas.setHeight(canvasHeight + "px"); displayComponentPanel.setHeight(getOffsetHeight() + "px"); displayComponentPanel.setWidgetPosition(bottomBar, 0, getOffsetHeight() - bottomBar.getOffsetHeight()); } @Override public void setWidth(String width) { super.setWidth(width); canvas.setWidth(getOffsetWidth() + "px"); displayComponentPanel.setWidth(getOffsetWidth() + "px"); } @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 (mouseScrollReg != null) { mouseScrollReg.removeHandler(); mouseScrollReg = null; } if (preview != null) { preview.removeHandler(); preview = null; } } @SuppressWarnings("deprecation") private void plotHorizontalScale(long startTime, long endTime, long unitTime, float xUnit, boolean leftAlign) { if (unitTime <= 0 || xUnit <= 0) { return; } float width = unitTime * xUnit; boolean shortDateFormat = width < 100; int year = widget.getStartDate().getYear(); long time = (new Date(year, 0, 1)).getTime(); DateTimeFormat formatter; if (unitTime < DAY) { formatter = shortDateFormat ? timeFormatShort : timeFormatLong; } else if (unitTime < MONTH) { formatter = shortDateFormat ? dayFormatShort : dayFormatLong; } else if (unitTime < YEAR) { formatter = shortDateFormat ? monthFormatShort : monthFormatLong; } else { formatter = shortDateFormat ? yearFormatShort : yearFormatLong; } if (gridColor != null) { canvas.setStrokeStyle(gridColor); canvas.setLineWidth(0.8); canvas.beginPath(); } long stepsUntilInRange = (startTime - time) / unitTime; time += stepsUntilInRange * unitTime; while (time <= endTime) { if (time >= startTime - unitTime && time <= endTime + unitTime) { Label lbl = new Label(); lbl.setStyleName(leftAlign ? CLASSNAME_SCALEDATE_LEFT : CLASSNAME_SCALEDATE); lbl.setWidth(width + "px"); Date date = new Date(time); lbl.setText(widget.getDateTimeService().formatDate(date, formatter.getPattern())); long timeFromStart = time - startTime; float x = timeFromStart * xUnit; if (gridColor != null) { canvas.moveTo(x, 0); canvas.lineTo(x, canvas.getHeight()); } displayComponentPanel.add(lbl, (int) x, displayComponentPanel.getOffsetHeight() - 15); horizontalScaleComponents.add(lbl); } if (unitTime == MONTH) { /* * Month resolution is not so easy since it changes depending on * the month. We use the Date to resolve the new time */ time += DateTimeService.getNumberOfDaysInMonth(new Date(time)) * DAY; } else if (unitTime == YEAR) { /* * Take leap years into account */ if (DateTimeService.isLeapYear(new Date(time))) { time += unitTime + DAY; } else { time += unitTime; } } else { time += unitTime; } } if (gridColor != null) { canvas.closePath(); canvas.stroke(); } } /** * Plots the horizontal scale */ private void plotHorizontalScale(float xUnit, long startTime, long endTime) { long timeDiff = endTime - startTime; for (Label lbl : horizontalScaleComponents) { displayComponentPanel.remove(lbl); } horizontalScaleComponents.clear(); canvas.setGlobalCompositeOperation(Canvas.DESTINATION_OVER); // Selection is less than a minute if (timeDiff <= VEventTimelineDisplay.MINUTE) { plotHorizontalScale(startTime, endTime, 10 * VEventTimelineDisplay.SECOND, xUnit, true); } // Selections is less the 5 minutes else if (timeDiff <= 5 * MINUTE) { plotHorizontalScale(startTime, endTime, VEventTimelineDisplay.MINUTE, xUnit, true); } // Selection is less than 30 minutes else if (timeDiff <= 30 * MINUTE) { plotHorizontalScale(startTime, endTime, 5 * MINUTE, xUnit, true); } // Selection is less than 1 hour else if (timeDiff <= HOUR) { plotHorizontalScale(startTime, endTime, 10 * MINUTE, xUnit, true); } // Selection is less then 6 hours else if (timeDiff <= 6 * HOUR) { plotHorizontalScale(startTime, endTime, 30 * MINUTE, xUnit, true); } // Selection is less then a half day else if (timeDiff <= 12 * HOUR) { plotHorizontalScale(startTime, endTime, HOUR, xUnit, false); } // Selection is less than a day else if (timeDiff <= DAY) { plotHorizontalScale(startTime, endTime, 2 * HOUR, xUnit, true); } // Selection is less than 3 days else if (timeDiff <= 3 * DAY) { plotHorizontalScale(startTime, endTime, 6 * HOUR, xUnit, true); } // Selection is less than a week. Show dayly view else if (timeDiff <= WEEK) { plotHorizontalScale(startTime, endTime, DAY, xUnit, false); } // Selection is less than two weeks else if (timeDiff <= 2 * WEEK) { plotHorizontalScale(startTime, endTime, 3 * DAY, xUnit, true); } // Selection is less than a month. Show weekly view else if (timeDiff <= 2 * MONTH) { plotHorizontalScale(startTime, endTime, WEEK, xUnit, true); } // Selection is less than two years else if (timeDiff <= 2 * YEAR) { plotHorizontalScale(startTime, endTime, MONTH, xUnit, false); } // Selection is more than two years else { plotHorizontalScale(startTime, endTime, YEAR, xUnit, false); } canvas.setGlobalCompositeOperation(Canvas.SOURCE_OVER); } public void redraw() { plotData(true); } private void plotData(boolean force) { // set the text fields with the correct date widget.setFromDateTextField(currentStartDate); widget.setToDateTextField(currentEndDate); // calculate some needed values Float canvasWidth = new Float(canvas.getWidth()); // Float canvasHeight = new Float(canvas.getWidth()); Long startTime = currentStartDate.getTime(); Long endTime = currentEndDate.getTime(); Long timeDiff = endTime - startTime; // ensure we have something to plot if (timeDiff <= 0) { return; } Float xUnit = canvasWidth / timeDiff.floatValue(); // clear old drawings canvas.clear(); // draw current time if it is in the current display Date d = new Date(); float timeX = (d.getTime() - startTime) * xUnit; if (timeX > 0 && timeX < canvas.getWidth()) { canvas.beginPath(); canvas.moveTo(timeX, canvas.getWidth()); canvas.lineTo(timeX, 0); canvas.closePath(); canvas.setStrokeStyle("#a00000"); canvas.setLineWidth(1.0d); canvas.stroke(); } if (force) { // remove old events for (VEventLabel w : events) { displayComponentPanel.remove(w); } events.clear(); } // if there are no event widgets yet, force creation if (events.isEmpty()) { force = true; } float y = 5; if (!force) { // in case a redraw is not forced, just move the existing labels // this is an optimization in case the user is dragging the display for (VEventLabel w : events) { VEvent event = w.getEvent(); Long eventStartTime = event.getStartTime(); Long timeFromStart = eventStartTime - startTime; float x = timeFromStart * xUnit; DOM.setStyleAttribute(w.getElement(), "left", x + "px"); } } else { // paint events for (Integer band : currentEvents.keySet()) { List<VEvent> eventList = currentEvents.get(band); int bandHeight = widget.getBandHeight(band); int slots = maxSlots.get(band); if (bandHeight > 0) { for (int idx = 0; idx < eventList.size(); idx++) { VEvent event = eventList.get(idx); Long eventStartTime = event.getStartTime(); Long eventEndTime = event.getEndTime(); Long timeFromStart = eventStartTime - startTime; float x = timeFromStart * xUnit; Long duration = eventEndTime - eventStartTime; float w = duration * xUnit; int cw = canvas.getWidth(); if ((x >= 0 && x + w < cw) || (x < 0 && x + w > 0 && x + w < cw) || (x >= 0 && x < cw && x + w > cw) || (x <= 0 && x + w > cw)) { if (force) { int height = Math.max(0, bandHeight - 6); plotEvent(event, x, y, w, slots, height); } } } y += bandHeight; } } } // paint horizontal lines to separate bands canvas.setStrokeStyle("#000"); canvas.setLineWidth(0.5); canvas.beginPath(); y = 1; for (Integer band : currentEvents.keySet()) { y += widget.getBandHeight(band); canvas.moveTo(0, y); canvas.lineTo(canvas.getWidth(), y); } canvas.closePath(); canvas.stroke(); // plot the horizontal scale plotHorizontalScale(xUnit, startTime, endTime); } private int checkOverlaps(List<VEvent> events, Long startTime, Long endTime) { ArrayList<VEvent> slots = new ArrayList<VEvent>(); // first sweep get maximum slots for (VEvent event : events) { if (slots.isEmpty()) { slots.add(event); event.setSlotIndex(0); event.setHeight(1); } else { boolean foundSlot = false; for (int slotIdx = 0; slotIdx < slots.size(); slotIdx++) { VEvent slotEvent = slots.get(slotIdx); boolean overlaps = overlaps(slotEvent, event); if (foundSlot) { if (overlaps) { event.setHeight(slotIdx - event.getSlotIndex()); break; } } else { if (!overlaps) { slots.set(slotIdx, event); event.setSlotIndex(slotIdx); event.setHeight(1); foundSlot = true; } } } if (!foundSlot) { slots.add(event); event.setSlotIndex(slots.size() - 1); event.setHeight(1); } } } return slots.size(); } public boolean overlaps(VEvent evt1, VEvent evt2) { if ((evt1.getStartTime() >= evt2.getStartTime() && evt1.getStartTime() <= evt2.getEndTime()) || (evt2.getStartTime() >= evt1.getStartTime() && evt2.getStartTime() <= evt1.getEndTime())) { return true; } else { return false; } } /** * Plots an event onto the display * * @param caption * The caption that shows on the screen * @param date * The date the event happened * @param index * The server index of the event * @param x * The X-coordinate * @param y * The Y-coordinate * @param w * The width * @param maxHeight * The maximum height of the event */ private void plotEvent(VEvent event, float x, float y, float w, int slots, int maxHeight) { int space = 3; float slotHeight = (float) maxHeight / (float) slots; int slotPosition = (int) (slotHeight * (float) event.getSlotIndex()); int elementHeight = (int) (slotHeight * (float) event.getHeight()) - space; final VEventLabel eventElement = new VEventLabel(event, w, Math.max(0, elementHeight)); displayComponentPanel.add(eventElement, (int) x, (int) y + slotPosition); String bg = ComputedStyle.getBackgroundColor(eventElement.getElement()); event.setBackgroundColor(bg); events.add(eventElement); } public void dataReceived(Integer band, List<VEvent> events) { // Check if we have events if (events != null) { currentEvents.put(band, events); Long startTime = currentStartDate.getTime(); Long endTime = currentEndDate.getTime(); int slots = checkOverlaps(events, startTime, endTime); maxSlots.put(band, slots); } } public void dataReceivedAll() { // we have received data for all bands, redraw now the display plotData(forcePlot); // forced plotting is always turned off after a forced plot. // To force it again you have to set it on again be // before the next plot. forcePlot = false; // hide curtain setLoadingIndicatorVisible(false); } @Override public void dataRemoved(Integer[] bands) { for (int i = 0; i < bands.length; i++) { Integer band = bands[i]; // Check if we have events if (events != null) { currentEvents.remove(band); maxSlots.remove(band.intValue()); // // we have received data for all bands, redraw now the // display // plotData(forcePlot); // // // forced plotting is always turned off after a forced plot. // // To force it again you have to set it on again be // // before the next plot. // forcePlot = false; // // // hide curtain // setLoadingIndicatorVisible(false); } } } /** * Should the spinning loading indicator be visible? * * @param visible * Is it visible */ private void setLoadingIndicatorVisible(boolean visible) { loadingCurtain.setVisible(visible); } public boolean setRange(Date start, Date end) { if (mouseIsActive) { // if we are dragging then ignore any setRange requests return false; } return setRange(start, end, false, false, true); } /** * Set the range to display * * @param start * The start date * @param end * The end date * @return */ private boolean setRange(Date start, Date end, Boolean useCurtain, boolean forceServer, boolean forceRedraw) { if (!isVisible()) { return false; } if (start == null || end == null) { return false; } currentStartDate = start; currentEndDate = end; if (forceRedraw) { resetDisplayCache(); // Get the events forcePlot = true; boolean cached = widget.getEvents(this, start, end, !forceServer); setLoadingIndicatorVisible(useCurtain && !cached); } else { plotData(false); } return true; } /** * Resets the display cache */ public void resetDisplayCache() { currentEvents.clear(); } /** * Returns the canvas width * * @return The width in pixels */ public int getCanvasWidth() { return canvas.getWidth(); } /** * Get the current starting date * * @return The date */ public Date getSelectionStartDate() { return currentStartDate; } /** * Get the current ending date * * @return The date */ public Date getSelectionEndDate() { return currentEndDate; } /** * Triggered when an VEvent widget is pressed * * @param eventElement */ private void eventClick(VEventLabel eventElement) { VEvent event = eventElement.getEvent(); widget.fireEventButtonClickEvent(event.getID()); } /** * Does the component have an specific element * * @param elem * The element * @return True if the component has the element */ public boolean hasElement(com.google.gwt.dom.client.Element elem) { for (Label lbl : horizontalScaleComponents) { if (lbl.getElement() == elem) { return true; } } for (Label lbl : verticalScaleComponents) { if (lbl.getElement() == elem) { return true; } } for (VEventLabel eventWidget : events) { if (eventWidget.getElement() == elem) { return true; } } if (elem == displayComponentPanel.getElement() || elem == getElement() || elem == canvas.getElement() || elem == loadingCurtain.getElement() || elem == browserRoot || elem == bottomBar.getElement() || elem == disabledCurtain.getElement()) { return true; } else { return false; } } /** * Displays the no data found message * * @param enabled * Is the message displayed */ public void displayNoDataMessage(boolean enabled) { noDataLabel.setVisible(enabled); setLoadingIndicatorVisible(false); } /** * Is the display enabled * * @param enabled * True if enabled */ public void setEnabled(boolean enabled) { this.enabled = enabled; setLoadingIndicatorVisible(false); } /** * Force plotting the the data even if it is the same time range. Forced * plotting is always turned off after a forced plot so you will have to * turn on forced plotting again before the next plot. * * @param enabled * The plotting is forced */ public void setForcedPlotting(boolean enabled) { forcePlot = enabled; } /** * Sets the scale grid color, set to null to not draw the grid * * @param color * The color */ public void setGridColor(String color) { gridColor = color; } int dragX = 0; private Command drag = new Command() { public void execute() { Long timeDiff = currentEndDragDate.getTime() - currentStartDragDate.getTime(); float xdiff = (dragX - mouseDownX) / 2f; float canvasWidth = canvas.getWidth(); float widthUnit = xdiff / canvasWidth; Float time = timeDiff * widthUnit; Long start = currentStartDate.getTime() - time.longValue(); Long end = currentEndDate.getTime() - time.longValue(); Date startDate = new Date(start); Date endDate = new Date(end); setRange(startDate, endDate, false, false, false); widget.setBrowserRange(startDate, endDate); mouseDownX = dragX; } }; /* * (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(); lastMouseX = event.getClientX(); // Dragging action occurring.. if (mouseIsDown && enabled && currentEndDragDate != null && currentStartDragDate != null) { dragX = mouseEvent.getClientX(); drag.execute(); // Mouse is hovering over the display area } else if (enabled) { // int x = mouseEvent.getClientX() - getAbsoluteLeft(); // int y = mouseEvent.getClientY() - getAbsoluteTop(); } } /* * (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(canvas.getElement()); if (enabled && currentEndDragDate != null && currentStartDragDate != null) { Long timeDiff = currentEndDragDate.getTime() - currentStartDragDate.getTime(); float xdiff = (lastMouseX - mouseDownX) / 2f; float canvasWidth = canvas.getWidth(); float widthUnit = xdiff / canvasWidth; Float time = timeDiff * widthUnit; Long start = currentStartDate.getTime() - time.longValue(); Long end = currentEndDate.getTime() - time.longValue(); Date startDate = new Date(start); Date endDate = new Date(end); if (startDate.compareTo(widget.getStartDate()) >= 0 && endDate.compareTo(widget.getEndDate()) <= 0) { // only trigger a redraw of the display, if the mouse has been // moved (dragged) boolean mouseMoved = startDate.compareTo(currentStartDragDate) != 0; if (mouseMoved && setRange(startDate, endDate, true, false, true)) { // widget.setBrowserRange(startDate, endDate); mouseDownX = lastMouseX; widget.fireDateRangeChangedEvent(); } } for (Label lbl : verticalScaleComponents) { lbl.setStyleName(CLASSNAME_SCALEVALUE); } canvas.setStyleName(CLASSNAME_CANVAS); currentStartDragDate = null; currentEndDragDate = null; } } /* * (non-Javadoc) * * @see * com.google.gwt.event.dom.client.MouseDownHandler#onMouseDown(com.google * .gwt.event.dom.client.MouseDownEvent) */ public void onMouseDown(MouseDownEvent event) { NativeEvent mouseEvent = event.getNativeEvent(); mouseIsActive = true; event.preventDefault(); event.stopPropagation(); if (enabled) { mouseDownX = mouseEvent.getClientX(); canvas.setStyleName(CLASSNAME_CANVASDRAG); for (Label lbl : verticalScaleComponents) { lbl.setStyleName(CLASSNAME_SCALEVALUEDRAG); } DOM.setCapture(canvas.getElement()); currentStartDragDate = new Date(currentStartDate.getTime()); currentEndDragDate = new Date(currentEndDate.getTime()); } // Remove the selected style from the widget again for (VEventLabel w : events) { w.removeStyleName(CLASSNAME_EVENT_SELECTED); } // Check if element is a event button for (VEventLabel w : events) { w.removeStyleName(CLASSNAME_EVENT_SELECTED); com.google.gwt.dom.client.Element mouseEventElement = Element.as(mouseEvent.getEventTarget()); if (mouseEventElement == w.getElement() || mouseEventElement.getParentElement() == w.getElement()) { w.addStyleName(CLASSNAME_EVENT_SELECTED); eventClick(w); break; } } } public void onMouseWheel(MouseWheelEvent event) { NativeEvent mouseEvent = event.getNativeEvent(); if (hasElement(Element.as(mouseEvent.getEventTarget()))) { event.preventDefault(); float x = mouseEvent.getClientX(); boolean up = mouseEvent.getMouseWheelVelocityY() > 0; float canvasWidth = canvas.getWidth(); float ratio = x / canvasWidth; // Calculate the minimum timeunit for the whole range long diff = widget.getEndDate().getTime() - widget.getStartDate().getTime(); float minTimeSpan = (diff / canvasWidth) * 60f; float minAllowedTimeSpan = (diff / canvasWidth) * 20f; Float startRatio = ratio * minTimeSpan; Float endRatio = (1f - ratio) * minTimeSpan; if (up) { Date start = new Date(currentStartDate.getTime() - startRatio.longValue()); if (start.before(widget.getStartDate())) { /* * Ensure we are in bounds */ start = widget.getStartDate(); } Date end = new Date(currentEndDate.getTime() + endRatio.longValue()); if (end.after(widget.getEndDate())) { /* * Ensure we are in bounds */ end = widget.getEndDate(); } if (end.getTime() - start.getTime() > minAllowedTimeSpan) { currentStartDate = start; currentEndDate = end; refresh(); widget.setBrowserRange(currentStartDate, currentEndDate); } } else { Date start = new Date(currentStartDate.getTime() + startRatio.longValue()); if (start.before(widget.getStartDate())) { /* * Ensure we are in bounds */ start = widget.getStartDate(); } Date end = new Date(currentEndDate.getTime() - endRatio.longValue()); if (end.after(widget.getEndDate())) { /* * Ensure we are in bounds */ end = widget.getEndDate(); } if (end.getTime() - start.getTime() > minAllowedTimeSpan) { currentStartDate = start; currentEndDate = end; refresh(); widget.setBrowserRange(currentStartDate, currentEndDate); } } } } public void onPreviewNativeEvent(NativePreviewEvent event) { // Monitor mouse button state if (event.getTypeInt() == Event.ONMOUSEUP && event.getNativeEvent().getButton() == NativeEvent.BUTTON_LEFT) { mouseIsDown = false; if (mouseIsActive) { onMouseUp(null); } } else if (event.getTypeInt() == Event.ONMOUSEDOWN && event.getNativeEvent().getButton() == NativeEvent.BUTTON_LEFT) { mouseIsDown = true; } } /** * Initializes the canvas i.e. it will fetch the points for the whole * timeline and render it to the canvas. */ public void refresh() { if (!isVisible()) { return; } setRange(getSelectionStartDate(), getSelectionEndDate(), false, false, true); } public void setYearFormatShort(DateTimeFormat format) { this.yearFormatShort = format; } public void setYearFormatLong(DateTimeFormat format) { this.yearFormatLong = format; } public void setMonthFormatShort(DateTimeFormat format) { this.monthFormatShort = format; } public void setMonthFormatLong(DateTimeFormat format) { this.monthFormatLong = format; } public void setDayFormatShort(DateTimeFormat format) { this.dayFormatShort = format; } public void setDayFormatLong(DateTimeFormat format) { this.dayFormatLong = format; } public void setTimeFormatShort(DateTimeFormat format) { this.timeFormatShort = format; } public void setTimeFormatLong(DateTimeFormat format) { this.timeFormatLong = format; } public boolean isMouseActive() { return mouseIsActive; } }