Java tutorial
/* @VaadinAddonLicenseForJavaFiles@ */ package com.spaceapplications.vaadin.addon.eventtimeline.gwt.client; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; import com.google.gwt.canvas.dom.client.CssColor; import com.google.gwt.dom.client.NativeEvent; import com.google.gwt.event.dom.client.DoubleClickEvent; import com.google.gwt.event.dom.client.DoubleClickHandler; 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.i18n.client.DateTimeFormat.PredefinedFormat; 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.Timer; 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.vaadin.terminal.gwt.client.DateTimeService; /** * VEventTimelineBrowser, based on original version from vaadin-timeline. * * @author Thomas Neidhart / Space Applications Services NV/SA * @author Peter Lehto / IT Mill Oy Ltd * @author John Ahlroos / IT Mill Oy Ltd */ public class VEventTimelineBrowser extends Widget implements VDataListener, MouseDownHandler, MouseMoveHandler, MouseUpHandler, MouseWheelHandler, DoubleClickHandler, NativePreviewHandler { private static final String CLASSNAME_CANVAS = VEventTimelineWidget.BROWSER_CLASSNAME + "-canvas"; private static final String CLASSNAME_SCROLLBAR = VEventTimelineWidget.BROWSER_CLASSNAME + "-scrollbar"; private static final String CLASSNAME_SCROLLBAR_LEFT = CLASSNAME_SCROLLBAR + "-left"; private static final String CLASSNAME_SCROLLBAR_RIGHT = CLASSNAME_SCROLLBAR + "-right"; private static final String CLASSNAME_FADE = CLASSNAME_SCROLLBAR + "-fade"; private static final String CLASSNAME_SCALE = VEventTimelineWidget.BROWSER_CLASSNAME + "-scale"; private static final String CLASSNAME_SCALELABEL = CLASSNAME_SCALE + "-label"; private static final String CLASSNAME_CURTAIN = VEventTimelineWidget.BROWSER_CLASSNAME + "-curtain"; private final Element browserRoot; private final Canvas canvas; private final Element scrollBar; private final Element scrollLeft; private final Element scrollRight; private boolean mouseDown; private boolean mouseIsActive = false; private final VEventTimelineWidget timelineWidget; private boolean sizeAdjustLeft; private boolean sizeAdjustRight; private int dragStartX; private final VEventTimelineBrowserScroller scroller = new VEventTimelineBrowserScroller(); private final Map<Integer, Set<VEvent>> currentEvents = new TreeMap<Integer, Set<VEvent>>(); private final Element leftFade; private final Element rightFade; private Date selectedStartDate = null; private Date selectedEndDate = null; private final AbsolutePanel horizontalScalePanel; private final List<Label> horizontalScaleComponents = new ArrayList<Label>(); private final HTML disabledCurtain; private HandlerRegistration mouseMoveReg, mouseUpReg, mouseDownReg, mouseScrollReg, mouseClickReg, preview; private DateTimeFormat yearFormatShort = DateTimeFormat.getFormat("''yy"); private DateTimeFormat yearFormatLong = DateTimeFormat.getFormat(PredefinedFormat.YEAR); private DateTimeFormat monthFormatShort = DateTimeFormat.getFormat(PredefinedFormat.YEAR_MONTH_ABBR); private DateTimeFormat monthFormatLong = DateTimeFormat.getFormat(PredefinedFormat.YEAR_MONTH); private DateTimeFormat dayFormatShort = DateTimeFormat.getFormat(PredefinedFormat.YEAR_MONTH_ABBR_DAY); private DateTimeFormat dayFormatLong = DateTimeFormat.getFormat(PredefinedFormat.YEAR_MONTH_DAY); private DateTimeFormat timeFormatShort = DateTimeFormat.getFormat(PredefinedFormat.HOUR24_MINUTE); private DateTimeFormat timeFormatLong = DateTimeFormat.getFormat(PredefinedFormat.HOUR24_MINUTE_SECOND); public VEventTimelineBrowser(VEventTimelineWidget tw) { timelineWidget = tw; browserRoot = DOM.createDiv(); setElement(browserRoot); setHeight("64px"); setStyleName(VEventTimelineWidget.BROWSER_CLASSNAME); canvas = new Canvas(300, 44); canvas.setStyleName(CLASSNAME_CANVAS); browserRoot.appendChild(canvas.getElement()); // Add the horizontal scale horizontalScalePanel = new AbsolutePanel(); horizontalScalePanel.setStyleName(CLASSNAME_SCALE); browserRoot.appendChild(horizontalScalePanel.getElement()); // Add fade-outs leftFade = DOM.createDiv(); leftFade.setClassName(CLASSNAME_FADE); browserRoot.appendChild(leftFade); rightFade = DOM.createDiv(); rightFade.setClassName(CLASSNAME_FADE); browserRoot.appendChild(rightFade); // Add the scrollbar scrollBar = DOM.createDiv(); scrollBar.setClassName(CLASSNAME_SCROLLBAR); scrollLeft = DOM.createDiv(); scrollLeft.setClassName(CLASSNAME_SCROLLBAR_LEFT); scrollRight = DOM.createDiv(); scrollRight.setClassName(CLASSNAME_SCROLLBAR_RIGHT); scrollBar.appendChild(scrollLeft); scrollBar.appendChild(scrollRight); browserRoot.appendChild(scrollBar); browserRoot.appendChild(scroller.getElement()); // Create the disabled curtain disabledCurtain = new HTML(""); disabledCurtain.setVisible(false); disabledCurtain.setStyleName(CLASSNAME_CURTAIN); disabledCurtain.setWidth("100%"); disabledCurtain.setHeight("100%"); disabledCurtain.getElement().getStyle().setZIndex(2); horizontalScalePanel.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()); mouseClickReg = addDomHandler(this, DoubleClickEvent.getType()); preview = Event.addNativePreviewHandler(this); } @Override public void setWidth(String width) { super.setWidth(width); int w = getOffsetWidth() - 28 - 2; canvas.setWidth(w + "px"); browserRoot.setAttribute("width", w + "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 (mouseClickReg != null) { mouseClickReg.removeHandler(); mouseClickReg = null; } if (preview != null) { preview.removeHandler(); preview = null; } } /** * 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() || timelineWidget.getStartDate() == null || timelineWidget.getEndDate() == null) { return; } // Get the events timelineWidget.getEvents(this, timelineWidget.getStartDate(), timelineWidget.getEndDate(), true); } public void redraw() { // Plot the points plotData(); // Set the scroller range // disable as this causes problems when an event is updated //setRange(selectedStartDate, selectedEndDate); } /* * (non-Javadoc) */ public void dataReceived(Integer band, List<VEvent> events) { if (events != null) { Set<VEvent> bandEvents = currentEvents.get(band); if (bandEvents == null) { bandEvents = new TreeSet<VEvent>(); currentEvents.put(band, bandEvents); } // TODO - Thomas -> what do you think about #clear()? // Should be OK since events always contains all events bandEvents.clear(); bandEvents.addAll(events); } } /* * (non-Javadoc) */ public void dataReceivedAll() { // Plot the received data plotData(); /* * If the selection is locked then we want to reset the range so it is * pointing to the same selection in case a point has been added or * removed from the graph. If the selection is not locked we need to * recalculate the new selection. */ if (timelineWidget.isInitDone() && timelineWidget.isSelectionLocked() && !mouseDown) { // disable as this causes problems when an event is updated //setRange(selectedStartDate, selectedEndDate); } else { refreshSelection(); } } @Override public void dataRemoved(Integer[] bands) { for (int i = 0; i < bands.length; i++) { Integer band = bands[i]; currentEvents.remove(band); } } /** * Plots the horizontal scale */ private void plotHorizontalScale(float xUnit, long startTime, long endTime) { long timeDiff = endTime - startTime; for (Label lbl : horizontalScaleComponents) { horizontalScalePanel.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); } // Selection is less than five minutes else if (timeDiff <= 5 * VEventTimelineDisplay.MINUTE) { plotHorizontalScale(startTime, endTime, VEventTimelineDisplay.MINUTE, xUnit, true); } // Selection is less than 30 minutes else if (timeDiff <= 30 * VEventTimelineDisplay.MINUTE) { plotHorizontalScale(startTime, endTime, 5 * VEventTimelineDisplay.MINUTE, xUnit, true); } // Selection is less than 1 hour else if (timeDiff <= VEventTimelineDisplay.HOUR) { plotHorizontalScale(startTime, endTime, 10 * VEventTimelineDisplay.MINUTE, xUnit, true); } // Selection is less then 6 hours else if (timeDiff <= 6 * VEventTimelineDisplay.HOUR) { plotHorizontalScale(startTime, endTime, 30 * VEventTimelineDisplay.MINUTE, xUnit, true); } // Selection is less then a half day else if (timeDiff <= 12 * VEventTimelineDisplay.HOUR) { plotHorizontalScale(startTime, endTime, VEventTimelineDisplay.HOUR, xUnit, false); } // Selection is less than a day else if (timeDiff <= VEventTimelineDisplay.DAY) { plotHorizontalScale(startTime, endTime, 2 * VEventTimelineDisplay.HOUR, xUnit, true); } // Selection is less than 3 days else if (timeDiff <= 3 * VEventTimelineDisplay.DAY) { plotHorizontalScale(startTime, endTime, 6 * VEventTimelineDisplay.HOUR, xUnit, true); } // Selection is less than a week. Show dayly view else if (timeDiff <= VEventTimelineDisplay.WEEK) { plotHorizontalScale(startTime, endTime, VEventTimelineDisplay.DAY, xUnit, false); } // Selection is less than two weeks else if (timeDiff <= 2 * VEventTimelineDisplay.WEEK) { plotHorizontalScale(startTime, endTime, 3 * VEventTimelineDisplay.DAY, xUnit, true); } // Selection is less than a month. Show weekly view else if (timeDiff <= 2 * VEventTimelineDisplay.MONTH) { plotHorizontalScale(startTime, endTime, VEventTimelineDisplay.WEEK, xUnit, true); } // Selection is less than a year else if (timeDiff <= 6 * VEventTimelineDisplay.MONTH) { plotHorizontalScale(startTime, endTime, VEventTimelineDisplay.MONTH, xUnit, false); } // Selection is less than a year else if (timeDiff <= VEventTimelineDisplay.YEAR) { plotHorizontalScale(startTime, endTime, VEventTimelineDisplay.MONTH, xUnit, false); } // Selection is more than two years else { plotHorizontalScale(startTime, endTime, VEventTimelineDisplay.YEAR, xUnit, false); } canvas.setGlobalCompositeOperation(Canvas.SOURCE_OVER); } @SuppressWarnings("deprecation") private void plotHorizontalScale(long startTime, long endTime, long unitTime, float xUnit, boolean leftAlign) { float width = unitTime * xUnit; boolean shortDateFormat = width < 100; int year = timelineWidget.getStartDate().getYear(); long time = (new Date(year, 0, 1)).getTime(); DateTimeFormat formatter; if (unitTime < VEventTimelineDisplay.DAY) { formatter = shortDateFormat ? timeFormatShort : timeFormatLong; } else if (unitTime < VEventTimelineDisplay.MONTH) { formatter = shortDateFormat ? dayFormatShort : dayFormatLong; } else if (unitTime < VEventTimelineDisplay.YEAR) { formatter = shortDateFormat ? monthFormatShort : monthFormatLong; } else { formatter = shortDateFormat ? yearFormatShort : yearFormatLong; } canvas.setStrokeStyle("rgb(200,200,200)"); 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(CLASSNAME_SCALELABEL); lbl.setWidth(width + "px"); Date date = new Date(time); lbl.setText(formatter.format(date)); long timeFromStart = time - startTime; float x = timeFromStart * xUnit; canvas.moveTo(x, 0); canvas.lineTo(x, canvas.getHeight()); horizontalScalePanel.add(lbl, (int) x + 14 + 1, horizontalScalePanel.getOffsetHeight() - scrollBar.getOffsetHeight() - 13); horizontalScaleComponents.add(lbl); } if (unitTime == VEventTimelineDisplay.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)) * VEventTimelineDisplay.DAY; } else if (unitTime == VEventTimelineDisplay.YEAR) { /* * Take leap years into account */ if (DateTimeService.isLeapYear(new Date(time))) { time += unitTime + VEventTimelineDisplay.DAY; } else { time += unitTime; } } else { time += unitTime; } } canvas.closePath(); canvas.stroke(); } /** * Plots the received data on to the canvas */ private void plotData() { if (!isVisible()) { return; } Float canvasWidth = (float) getCanvasWidth(); Float canvasHeight = new Float(canvas.getHeight()); // clear old drawings canvas.clear(); Long timeDiff = timelineWidget.getEndDate().getTime() - timelineWidget.getStartDate().getTime(); float xUnit = canvasWidth / timeDiff.floatValue(); // draw current time if it is in the current display Date d = new Date(); float timeX = (d.getTime() - timelineWidget.getStartDate().getTime()) * xUnit; if (timeX > 0 && timeX < canvas.getWidth()) { canvas.beginPath(); canvas.moveTo(timeX, canvas.getHeight()); canvas.lineTo(timeX, 0); canvas.closePath(); canvas.setStrokeStyle("#a00000"); canvas.setLineWidth(1.0d); canvas.stroke(); } // plot the events, the bands heights are evenly distributed int numBands = currentEvents.size(); int bandHeight = canvasHeight.intValue() - 10; if (numBands > 0) { bandHeight = bandHeight / numBands - 2; } float y = 1; long startTime = timelineWidget.getStartDate().getTime(); for (Set<VEvent> eventSet : currentEvents.values()) { float lastX = 0; for (VEvent event : eventSet) { Long eventStartTime = event.getStartTime(); Long eventEndTime = event.getEndTime(); Long timeFromStart = eventStartTime - startTime; float x = timeFromStart * xUnit; Long duration = eventEndTime - eventStartTime; float w = duration * xUnit; if (x < lastX) { w -= lastX - x; x = lastX; } plotEvent(event, x, y, w, bandHeight); lastX = x + w; } y += bandHeight + 2; } // plot the horizontal scale plotHorizontalScale(xUnit, timelineWidget.getStartDate().getTime(), timelineWidget.getEndDate().getTime()); } /** * Plots an event onto the display * * @param event * The event * @param x * The X-coordinate * @param y * The Y-coordinate * @param w * The width * @param h * The height */ private void plotEvent(VEvent event, float x, float y, float w, float h) { canvas.save(); canvas.beginPath(); canvas.rect(x, y, w, h); canvas.closePath(); canvas.setLineWidth(0.5); canvas.setStrokeStyle("#ccc"); String bgColor = event.getBackgroundColor(); String fillStyle = (bgColor == null) ? "#ccc" : CssColor.make(bgColor).value(); canvas.setFillStyle(fillStyle); canvas.stroke(); canvas.fill(); canvas.restore(); } /** * Set the selected range * * @param startDate * The start date of the range * @param endDate * The end date of the range */ public void setRange(Date startDate, Date endDate) { Date start = timelineWidget.getStartDate(); Date end = timelineWidget.getEndDate(); if (startDate == null || startDate.before(start)) { startDate = start; } if (endDate == null || endDate.after(end)) { endDate = end; } selectedStartDate = startDate; selectedEndDate = endDate; Long timeDiff = end.getTime() - start.getTime(); Float timeUnit = (float) canvas.getOffsetWidth() / (float) timeDiff; Long startTime = startDate.getTime() - start.getTime(); int startPixel = (int) (startTime * timeUnit) + 14; Long endTime = endDate.getTime() - start.getTime(); int endPixel = (int) (endTime * timeUnit) - 3; if (startPixel < 14) { startPixel = 14; } if (endPixel > getOffsetWidth() - 16) { endPixel = getOffsetWidth() - 16; } scroller.setLeftPosition(startPixel); scroller.setRightPosition(endPixel); DOM.setStyleAttribute(leftFade, "width", startPixel + "px"); DOM.setStyleAttribute(rightFade, "left", (endPixel + 14 + 2) + "px"); DOM.setStyleAttribute(rightFade, "width", (getOffsetWidth() - endPixel - 28) + "px"); } /** * Converts the selectors start pixel position to a date * * @return The calculated date */ private Date calculateStartPoint() { Date start = timelineWidget.getStartDate(); Date end = timelineWidget.getEndDate(); Float canvasWidth = (float) getCanvasWidth(); Long timeDiff = end.getTime() - start.getTime(); Float timeUnit = timeDiff.floatValue() / canvasWidth; int selectorLeftPixel = scroller.getLeftPosition(); Float time = selectorLeftPixel * timeUnit; Date date = new Date(start.getTime() + time.longValue()); if (date.before(start)) { date = start; } if (date.after(end)) { date = end; } return date; } /** * Converts the selectors end pixel position to a date * * @return The calculated date */ private Date calculateEndPoint() { Date start = timelineWidget.getStartDate(); Date end = timelineWidget.getEndDate(); Float canvasWidth = (float) getCanvasWidth(); Long timeDiff = end.getTime() - start.getTime(); Float timeUnit = timeDiff.floatValue() / canvasWidth; int selectorRightPixel = scroller.getRightPosition(); Float time = selectorRightPixel * timeUnit; Date date = new Date(start.getTime() + time.longValue()); if (date.before(start)) { date = start; } if (date.after(end)) { date = end; } return date; } /** * Alias for calculateStartPoint * * @return The calculated date */ public Date getSelectedStartDate() { return selectedStartDate; } /** * Alias for calculateEndPoint * * @return The calculated date */ public Date getSelectedEndDate() { return selectedEndDate; } /** * Get the canvas width * * @return The width in pixels */ public int getCanvasWidth() { if (isVisible()) { return canvas.getOffsetWidth(); } else { return timelineWidget.getWidgetWidth() - 28 - 2; } } /** * 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 == browserRoot || elem == leftFade || elem == rightFade || elem == scrollBar || elem == scrollLeft || elem == scrollRight || elem == canvas.getElement() || elem == horizontalScalePanel.getElement() || scroller.hasElement(elem) || elem == disabledCurtain.getElement()) { return true; } else { return false; } } /** * Enables the browser * * @param enabled * Is the browser usable by the user */ public void setEnabled(boolean enabled) { disabledCurtain.setVisible(!enabled); } /* * (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(horizontalScalePanel.getElement()); if (sizeAdjustLeft || sizeAdjustRight) { scroller.lockSize(); selectedStartDate = calculateStartPoint(); selectedEndDate = calculateEndPoint(); setDateRangeTimer.cancel(); setDateRangeTimer.schedule(100); DOM.setStyleAttribute(leftFade, "width", (scroller.getLeftPosition() + 14) + "px"); DOM.setStyleAttribute(rightFade, "left", (scroller.getRightPosition() + 14 + 2) + "px"); DOM.setStyleAttribute(rightFade, "width", (getOffsetWidth() - scroller.getRightPosition() - 28) + "px"); timelineWidget.fireDateRangeChangedEvent(); } else { selectedStartDate = calculateStartPoint(); selectedEndDate = calculateEndPoint(); setDateRangeTimer.cancel(); setDateRangeTimer.schedule(100); DOM.setStyleAttribute(leftFade, "width", (scroller.getLeftPosition() + 14) + "px"); DOM.setStyleAttribute(rightFade, "left", (scroller.getRightPosition() + 14 + 2) + "px"); DOM.setStyleAttribute(rightFade, "width", (getOffsetWidth() - scroller.getRightPosition() - 28) + "px"); timelineWidget.fireDateRangeChangedEvent(); } sizeAdjustLeft = false; sizeAdjustRight = false; } private Timer setDateRangeTimer = new Timer() { @Override public void run() { timelineWidget.setDisplayRange(selectedStartDate, selectedEndDate); } }; /* * (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.getClientX() - dragStartX; // The area size is being adjusted if (sizeAdjustLeft && scroller.getLeftPosition() + adjustment > 0) { if (scroller.getWidth() > adjustment) { scroller.adjustLeftSideSize(adjustment); } } else if (sizeAdjustLeft) { scroller.adjustLeftSideSize(-scroller.getLeftPosition()); } else if (sizeAdjustRight && scroller.getRightPosition() + adjustment < scrollBar.getOffsetWidth() - 2 * 15) { scroller.adjustRightSideSize(adjustment); } else if (sizeAdjustRight) { int diff = (scrollBar.getOffsetWidth() - 2 * 15) - scroller.getRightPosition(); scroller.adjustRightSideSize(diff - 1); } else { int scrollAreaX = mouseEvent.getClientX() - dragStartX; /* * Calculate the right edge. Remember to add the left and right * spacing 2*14px and the borders 2*1px to the calculation. */ int scrollAreaRight = scrollAreaX + scroller.getAreaWidth() + 14 + 2; if (scrollAreaRight <= scrollBar.getOffsetWidth()) { int offset = scroller.getMouseOffset((Event) mouseEvent); int leftPosition = mouseEvent.getClientX() - dragStartX; if (offset != dragStartX) { scroller.setLeftPosition(leftPosition); if (leftPosition > 14) { dragStartX = scroller.getMouseOffset((Event) mouseEvent); } selectedStartDate = calculateStartPoint(); selectedEndDate = calculateEndPoint(); setDateRangeTimer.cancel(); setDateRangeTimer.schedule(100); } /* * Else if the cursor is over the right edge make sure the * browser is in its rightmost position. */ } else { int width = scroller.getAreaWidth(); int leftPosition = scrollBar.getOffsetWidth() - width - 14; scroller.setLeftPosition(leftPosition); selectedStartDate = calculateStartPoint(); selectedEndDate = calculateEndPoint(); setDateRangeTimer.cancel(); setDateRangeTimer.schedule(100); } } DOM.setStyleAttribute(leftFade, "width", (scroller.getLeftPosition() + 14) + "px"); DOM.setStyleAttribute(rightFade, "left", (scroller.getRightPosition() + 14 + 2) + "px"); DOM.setStyleAttribute(rightFade, "width", (getOffsetWidth() - scroller.getRightPosition() - 28) + "px"); } } /* * (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(); Element mouseOver = (Element) Element.as(mouseEvent.getEventTarget()); mouseIsActive = true; event.preventDefault(); event.stopPropagation(); DOM.setCapture(horizontalScalePanel.getElement()); if (mouseOver == scrollLeft) { sizeAdjustLeft = false; sizeAdjustRight = false; if (scroller.getLeftPosition() > 0) { scroller.move(-1); timelineWidget.fireDateRangeChangedEvent(); } } else if (mouseOver == scrollRight) { sizeAdjustLeft = false; sizeAdjustRight = false; if (scroller.getRightPosition() + 5 < getCanvasWidth()) { scroller.move(1); timelineWidget.fireDateRangeChangedEvent(); } } else if (scroller.isMouseOverScrollElement((Event) mouseEvent) || scroller.isMouseOverScrollArea((Event) mouseEvent)) { sizeAdjustLeft = false; sizeAdjustRight = false; dragStartX = scroller.getMouseOffset((Event) mouseEvent); } else if (scroller.isMouseOverLeftSideSizeAdjuster((Event) mouseEvent)) { sizeAdjustRight = false; sizeAdjustLeft = true; dragStartX = mouseEvent.getClientX(); } else if (scroller.isMouseOverRightSideSizeAdjuster((Event) mouseEvent)) { sizeAdjustLeft = false; sizeAdjustRight = true; dragStartX = mouseEvent.getClientX(); } else if (mouseOver == horizontalScalePanel.getElement() || mouseOver == leftFade || mouseOver == rightFade) { sizeAdjustLeft = false; sizeAdjustRight = false; // Calculate the centering point int center = mouseEvent.getClientX() - getAbsoluteLeft(); int area = scroller.getAreaWidth(); if (center - area / 2 < 14) { center = area / 2; } if (center + area / 2 > getOffsetWidth() - 28) { center = getOffsetWidth() - 28 - area / 2; } // Center scoller and set fades scroller.center(center); DOM.setStyleAttribute(leftFade, "width", (scroller.getLeftPosition() + 14) + "px"); DOM.setStyleAttribute(rightFade, "left", (scroller.getRightPosition() + 14 + 2) + "px"); DOM.setStyleAttribute(rightFade, "width", (getOffsetWidth() - scroller.getRightPosition() - 28) + "px"); dragStartX = scroller.getMouseOffset((Event) mouseEvent); setDateRangeTimer.cancel(); setDateRangeTimer.schedule(100); } } private int scrollAdjustLeft = 0; private int scrollAdjustRight = 0; private Timer scrollTimer = new Timer() { @Override public void run() { // Check that we are not scrolling over the left side if (scroller.getLeftPosition() + scrollAdjustLeft >= 0) { scroller.adjustLeftSideSize(scrollAdjustLeft); } else { scroller.setLeftPosition(0); } // Check that we are not scrolling over the right side if (scroller.getRightPosition() + scrollAdjustRight <= getCanvasWidth() + 2) { scroller.adjustRightSideSize(scrollAdjustRight); } // Update refreshSelection(); scrollAdjustLeft = 0; scrollAdjustRight = 0; } }; public void onMouseWheel(MouseWheelEvent event) { NativeEvent mouseEvent = event.getNativeEvent(); event.preventDefault(); boolean up = mouseEvent.getMouseWheelVelocityY() > 0; // Only apply event to scroller if (!scroller.isMouseOverScrollArea((Event) mouseEvent)) { return; } sizeAdjustLeft = true; sizeAdjustRight = true; if (up) { scrollAdjustLeft += -5; scrollAdjustRight += 10; } else { scrollAdjustLeft += 5; scrollAdjustRight += -10; } scrollTimer.cancel(); scrollTimer.schedule(50); } /** * Refreshes selection, by recalculating position */ public void refreshSelection() { if (isVisible()) { selectedStartDate = calculateStartPoint(); selectedEndDate = calculateEndPoint(); } else { selectedStartDate = timelineWidget.getStartDate(); selectedEndDate = timelineWidget.getEndDate(); } setDateRangeTimer.cancel(); setDateRangeTimer.schedule(100); if (!mouseDown) { scroller.lockSize(); DOM.setStyleAttribute(leftFade, "width", (scroller.getLeftPosition() + 14) + "px"); DOM.setStyleAttribute(rightFade, "left", (scroller.getRightPosition() + 14 + 2) + "px"); DOM.setStyleAttribute(rightFade, "width", (getOffsetWidth() - scroller.getRightPosition() - 28) + "px"); sizeAdjustLeft = false; sizeAdjustRight = false; timelineWidget.fireDateRangeChangedEvent(); } } 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; } } public void onDoubleClick(DoubleClickEvent event) { NativeEvent mouseEvent = event.getNativeEvent(); if (scroller.isMouseOverScrollElement((Event) mouseEvent) || scroller.isMouseOverScrollArea((Event) mouseEvent)) { if (mouseEvent.getButton() == NativeEvent.BUTTON_LEFT) { scroller.setLeftPosition(0); scroller.setRightPosition(getOffsetWidth() - 28 - 2); refreshSelection(); } } } }