teichmann@5835: package org.dive4elements.river.client.client.ui.chart; ingo@551: ingo@551: import java.util.ArrayList; ingo@551: import java.util.List; ingo@551: ingo@551: import com.google.gwt.core.client.GWT; ingo@551: ingo@551: import com.smartgwt.client.types.SelectionType; ingo@551: import com.smartgwt.client.widgets.Canvas; ingo@553: import com.smartgwt.client.widgets.Img; ingo@551: import com.smartgwt.client.widgets.ImgButton; ingo@551: import com.smartgwt.client.widgets.events.MouseDownEvent; ingo@551: import com.smartgwt.client.widgets.events.MouseDownHandler; ingo@551: import com.smartgwt.client.widgets.events.MouseMoveEvent; ingo@551: import com.smartgwt.client.widgets.events.MouseMoveHandler; ingo@551: import com.smartgwt.client.widgets.events.MouseOutEvent; ingo@551: import com.smartgwt.client.widgets.events.MouseOutHandler; ingo@551: import com.smartgwt.client.widgets.events.MouseUpEvent; ingo@551: import com.smartgwt.client.widgets.events.MouseUpHandler; ingo@551: teichmann@5835: import org.dive4elements.river.client.client.event.HasPanHandlers; teichmann@5835: import org.dive4elements.river.client.client.event.PanEvent; teichmann@5835: import org.dive4elements.river.client.client.event.PanHandler; ingo@551: ingo@551: ingo@551: /** ingo@551: * @author Ingo Weinzierl ingo@551: */ ingo@551: public class PanControl ingo@551: extends ImgButton ingo@551: implements MouseDownHandler, MouseMoveHandler, MouseUpHandler, ingo@551: MouseOutHandler, HasPanHandlers ingo@551: { ingo@551: protected ChartOutputTab chartTab; ingo@551: ingo@551: protected List handlers; ingo@551: ingo@551: protected int[] start; ingo@551: protected int[] end; ingo@551: ingo@551: ingo@551: public PanControl(ChartOutputTab chartTab, String imageUrl) { ingo@551: super(); ingo@551: ingo@551: this.chartTab = chartTab; ingo@551: this.handlers = new ArrayList(); ingo@551: this.start = new int[] { -1, -1 }; ingo@551: this.end = new int[] { -1, -1 }; ingo@551: ingo@551: String baseUrl = GWT.getHostPageBaseURL(); ingo@551: setSrc(baseUrl + imageUrl); ingo@551: setActionType(SelectionType.CHECKBOX); ingo@551: setSize(20); ingo@551: setShowRollOver(false); ingo@551: setSelected(false); ingo@551: ingo@551: chartTab.getChartPanel().addMouseDownHandler(this); ingo@551: chartTab.getChartPanel().addMouseMoveHandler(this); ingo@551: chartTab.getChartPanel().addMouseUpHandler(this); ingo@551: chartTab.getChartPanel().addMouseOutHandler(this); ingo@551: } ingo@551: ingo@551: ingo@551: /** ingo@551: * Method used to register a new PanHandler. ingo@551: * ingo@551: * @param handler A new PanHandler. ingo@551: */ ingo@551: public void addPanHandler(PanHandler handler) { ingo@551: if (handler != null) { ingo@551: handlers.add(handler); ingo@551: } ingo@551: } ingo@551: ingo@551: ingo@551: /** ingo@551: * This event starts the dragging operation if the control is activated. ingo@551: * ingo@551: * @param event The mouse down event which contains the start coordinates. ingo@551: */ ingo@551: public void onMouseDown(MouseDownEvent event) { ingo@551: if (!isSelected()) { ingo@551: return; ingo@551: } ingo@551: ingo@551: start[0] = event.getX(); ingo@551: start[1] = event.getY(); ingo@551: ingo@551: end[0] = start[0]; ingo@551: end[1] = start[1]; ingo@551: } ingo@551: ingo@551: ingo@551: /** ingo@551: * This event is used to reposition the chart image based on the current ingo@551: * drag operation. ingo@551: * ingo@551: * @param event The move event which contains the new coordinates to update ingo@551: * the chart image position. ingo@551: */ ingo@551: public void onMouseMove(MouseMoveEvent event) { ingo@551: if (!isSelected() || start[0] == -1 || start[1] == -1) { ingo@551: return; ingo@551: } ingo@551: ingo@551: int x = event.getX() - end[0]; ingo@551: int y = event.getY() - end[1]; ingo@551: ingo@551: end[0] = end[0] + x; ingo@551: end[1] = end[1] + y; ingo@551: ingo@610: Canvas c = chartTab.getChartImg(); ingo@551: c.moveBy(x, y); ingo@551: } ingo@551: ingo@551: ingo@551: /** ingo@551: * This event stops the dragging operation and fires a DragEnd event to the ingo@551: * registered listeners. ingo@551: * ingo@551: * @param event The mouse up event which contains the end coordinates. ingo@551: */ ingo@551: public void onMouseUp(MouseUpEvent event) { ingo@551: if (!isSelected()) { ingo@551: return; ingo@551: } ingo@551: ingo@551: end[0] = event.getX(); ingo@551: end[1] = event.getY(); ingo@551: ingo@610: Canvas c = chartTab.getChartImg(); ingo@610: c.setLeft(0); ingo@610: c.setTop(0); ingo@551: ingo@551: fireOnPan(); ingo@551: ingo@551: start[0] = -1; ingo@551: start[1] = -1; ingo@551: } ingo@551: ingo@551: ingo@551: /** ingo@551: * This event is used to cancel the current dragging operation. ingo@551: * ingo@551: * @param event The mouse out event. ingo@551: */ ingo@551: public void onMouseOut(MouseOutEvent event) { ingo@553: int x = event.getX(); ingo@553: int y = event.getY(); ingo@553: ingo@553: if (!isSelected() || !isMouseOut(x, y) || start[0] == -1) { ingo@553: return; ingo@553: } ingo@553: ingo@610: Canvas c = chartTab.getChartImg(); ingo@610: c.setLeft(0); ingo@610: c.setTop(0); ingo@553: ingo@553: fireOnPan(); ingo@553: ingo@553: start[0] = -1; ingo@553: start[1] = -1; ingo@553: } ingo@553: ingo@553: ingo@553: /** ingo@553: * This method is required to check manually if the mouse pointer really ingo@553: * moves out the chart area. The MouseOutEvent is also fired if the mouse ingo@553: * goes down which doesn't seem to be correct. So, we gonna check this ingo@553: * manually. ingo@553: * ingo@553: * @param x The x coordinate. ingo@553: * @param y The y coordinate. ingo@553: * ingo@553: * @return true, if the mouse is really out of the chart area, otherwise ingo@553: * false. ingo@553: */ ingo@553: protected boolean isMouseOut(int x, int y) { ingo@610: Canvas chart = chartTab.getChartImg(); ingo@553: ingo@553: if (chart instanceof Img) { ingo@553: chart = chart.getParentElement(); ingo@553: } ingo@553: ingo@553: int left = chart.getPageLeft(); ingo@553: int right = chart.getPageRight(); ingo@553: int top = chart.getPageTop(); ingo@553: int bottom = chart.getPageBottom(); ingo@553: ingo@553: if (x <= left || x >= right || y <= top || y >= bottom) { ingo@553: return true; ingo@553: } ingo@553: ingo@553: return false; ingo@551: } ingo@551: ingo@551: ingo@551: /** ingo@551: * A pan event is fired to inform the registered listeners about a pan ingo@551: * operation has finished. ingo@551: */ ingo@551: protected void fireOnPan() { ingo@551: PanEvent event = new PanEvent(start, end); ingo@551: ingo@551: for (PanHandler handler: handlers) { ingo@551: handler.onPan(event); ingo@551: } ingo@551: } ingo@551: } ingo@551: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :