ingo@540: package de.intevation.flys.client.client.ui.chart;
ingo@540:
ingo@540: import java.util.ArrayList;
ingo@540: import java.util.List;
ingo@540:
ingo@540: import com.smartgwt.client.types.Positioning;
ingo@540: import com.smartgwt.client.types.SelectionType;
ingo@540: import com.smartgwt.client.widgets.Button;
ingo@540: import com.smartgwt.client.widgets.Canvas;
ingo@540: import com.smartgwt.client.widgets.events.MouseDownEvent;
ingo@540: import com.smartgwt.client.widgets.events.MouseDownHandler;
ingo@540: import com.smartgwt.client.widgets.events.MouseMoveEvent;
ingo@540: import com.smartgwt.client.widgets.events.MouseMoveHandler;
ingo@540: import com.smartgwt.client.widgets.events.MouseUpEvent;
ingo@540: import com.smartgwt.client.widgets.events.MouseUpHandler;
ingo@540:
ingo@540: import de.intevation.flys.client.client.event.HasZoomHandlers;
ingo@540: import de.intevation.flys.client.client.event.ZoomEvent;
ingo@540: import de.intevation.flys.client.client.event.ZoomHandler;
ingo@540:
ingo@540:
ingo@540: /**
ingo@540: * This control observes that panel retrieved by ChartOutputTab.getChartPanel().
ingo@540: * If activated, a zoombox is drawn. One of the two edges is the position of the
ingo@540: * mouse down event on the observed panel. The other edge is specified by the
ingo@540: * current mouse position. If the mouse up event occurs, start and end point
ingo@540: * relative to the left and upper border of the observed panel is determined and
ingo@540: * a ZoomEvent is fired.
ingo@540: *
ingo@540: * @author Ingo Weinzierl
ingo@540: */
ingo@540: public class ZoomboxControl
ingo@540: extends Button
ingo@540: implements MouseDownHandler, MouseUpHandler, MouseMoveHandler, HasZoomHandlers
ingo@540: {
ingo@540: protected List handlers;
ingo@540:
ingo@540: protected ChartOutputTab chartTab;
ingo@540:
ingo@540: protected Canvas zoombox;
ingo@540:
ingo@540: protected int[] start;
ingo@540: protected int[] end;
ingo@540:
ingo@540:
ingo@540: public ZoomboxControl(ChartOutputTab chartTab) {
ingo@540: super("Zoombox");
ingo@540:
ingo@540: this.handlers = new ArrayList();
ingo@540: this.chartTab = chartTab;
ingo@540: this.start = new int[2];
ingo@540: this.end = new int[2];
ingo@540: this.zoombox = new Canvas();
ingo@540:
ingo@540: initZoombox();
ingo@540:
ingo@540: setActionType(SelectionType.CHECKBOX);
ingo@540: setSelected(false);
ingo@540:
ingo@540: chartTab.getChartPanel().addMouseDownHandler(this);
ingo@540: chartTab.getChartPanel().addMouseMoveHandler(this);
ingo@540: chartTab.getChartPanel().addMouseUpHandler(this);
ingo@540: }
ingo@540:
ingo@540:
ingo@540: /**
ingo@540: * Initializes the zoombox that is displayed over the observed area. The
ingo@540: * zoombox has an opaque background. Its height/width and x/y values are
ingo@540: * determined by the start point (mouse down) and the current mouse
ingo@540: * position.
ingo@540: */
ingo@540: protected void initZoombox() {
ingo@540: zoombox.setPosition(Positioning.ABSOLUTE);
ingo@541: zoombox.setBorder("2px solid black");
ingo@540: zoombox.setOpacity(50);
ingo@540: zoombox.setWidth(0);
ingo@540: zoombox.setHeight(0);
ingo@540: }
ingo@540:
ingo@540:
ingo@540: /**
ingo@540: * Registers a new ZoomHandler that wants to listen to ZoomEvents.
ingo@540: *
ingo@540: * @param handler A new ZoomHandler.
ingo@540: */
ingo@540: public void addZoomHandler(ZoomHandler handler) {
ingo@540: if (handler != null) {
ingo@540: handlers.add(handler);
ingo@540: }
ingo@540: }
ingo@540:
ingo@540:
ingo@540: /**
ingo@540: * A mouse down event on the specified area will set the start point for the
ingo@540: * zoombox.
ingo@540: *
ingo@540: * @param event The mouse down event which contains the xy coordinates of
ingo@540: * the observed area.
ingo@540: */
ingo@540: public void onMouseDown(MouseDownEvent event) {
ingo@540: if (!isSelected()) {
ingo@540: return;
ingo@540: }
ingo@540:
ingo@540: start[0] = getRelativeX(event.getX());
ingo@540: start[1] = getRelativeY(event.getY());
ingo@540:
ingo@540: end[0] = start[0];
ingo@540: end[1] = start[1];
ingo@540:
ingo@540: chartTab.getChartPanel().addChild(zoombox);
ingo@540:
ingo@540: positionZoombox();
ingo@540: }
ingo@540:
ingo@540:
ingo@540: /**
ingo@540: * A mouse move event on the specified area will set the end point for the
ingo@540: * zoombox. If the end point differs from the start point, an opaque box is
ingo@540: * displayed.
ingo@540: *
ingo@540: * @param event The mouse move event which contains the xy coordinates of
ingo@540: * the observed area.
ingo@540: */
ingo@540: public void onMouseMove(MouseMoveEvent event) {
ingo@540: if (!isSelected()) {
ingo@540: return;
ingo@540: }
ingo@540:
ingo@540: end[0] = getRelativeX(event.getX());
ingo@540: end[1] = getRelativeY(event.getY());
ingo@540:
ingo@540: positionZoombox();
ingo@540: }
ingo@540:
ingo@540:
ingo@540: /**
ingo@540: * The mouse up event finalizes the zoom operation. It sets the end point
ingo@540: * for this operation, clears the zoombox and fires a ZoomEvent.
ingo@540: *
ingo@540: * @param event The mouse up event which contains the xy coordinates of the
ingo@540: * observed area.
ingo@540: */
ingo@540: public void onMouseUp(MouseUpEvent event) {
ingo@540: if (!isSelected()) {
ingo@540: return;
ingo@540: }
ingo@540:
ingo@540: end[0] = getRelativeX(event.getX());
ingo@540: end[1] = getRelativeY(event.getY());
ingo@540:
ingo@541: fireZoomEvent();
ingo@541:
ingo@540: clearZoombox();
ingo@540:
ingo@540: chartTab.getChartPanel().removeChild(zoombox);
ingo@540: }
ingo@540:
ingo@540:
ingo@540: /**
ingo@540: * Returns the X coordinate relative to the left border.
ingo@540: *
ingo@540: * @param x The X coordinate relative to the window.
ingo@540: *
ingo@540: * @return the X coordinate relative to the left border.
ingo@540: */
ingo@540: protected int getRelativeX(int x) {
ingo@540: return x - chartTab.getChartPanel().getPageLeft();
ingo@540: }
ingo@540:
ingo@540:
ingo@540: /**
ingo@540: * Returns the Y coordinate relative to the top border.
ingo@540: *
ingo@540: * @param y The Y coordinate relative to the window.
ingo@540: *
ingo@540: * @return the Y coordinate relative to the top border.
ingo@540: */
ingo@540: protected int getRelativeY(int y) {
ingo@540: return y - chartTab.getChartPanel().getPageTop();
ingo@540: }
ingo@540:
ingo@540:
ingo@540: /**
ingo@540: * Returns min and max x/y values based on the stored values in start
ingo@540: * and end.
ingo@540: *
ingo@540: * @return an int[] as follows: [xmin, ymin, xmax, ymax].
ingo@540: */
ingo@540: protected int[] orderPositions() {
ingo@540: int xmin = start[0] < end[0] ? start[0] : end[0];
ingo@540: int ymin = start[1] < end[1] ? start[1] : end[1];
ingo@540:
ingo@540: int xmax = start[0] >= end[0] ? start[0] : end[0];
ingo@540: int ymax = start[1] >= end[1] ? start[1] : end[1];
ingo@540:
ingo@540: return new int[] { xmin, ymin, xmax, ymax };
ingo@540: }
ingo@540:
ingo@540:
ingo@540: /**
ingo@540: * Sets the width, height, x and y values of the zoombox.
ingo@540: */
ingo@540: protected void positionZoombox() {
ingo@540: int[] values = orderPositions();
ingo@540:
ingo@540: zoombox.setLeft(values[0]);
ingo@540: zoombox.setTop(values[1]);
ingo@540: zoombox.setWidth(values[2] - values[0]);
ingo@540: zoombox.setHeight(values[3] - values[1]);
ingo@540: }
ingo@540:
ingo@540:
ingo@540: /**
ingo@540: * Clears the zoombox (set position and size to null).
ingo@540: */
ingo@540: protected void clearZoombox() {
ingo@540: zoombox.setLeft(0);
ingo@540: zoombox.setTop(0);
ingo@540: zoombox.setWidth(0);
ingo@540: zoombox.setHeight(0);
ingo@540: }
ingo@540:
ingo@540:
ingo@540: /**
ingo@540: * Fires a ZoomEvent to all registered listeners.
ingo@540: */
ingo@540: protected void fireZoomEvent() {
ingo@540: int[] pos = orderPositions();
ingo@540:
ingo@540: ZoomEvent event = new ZoomEvent(pos[0], pos[1], pos[2], pos[3]);
ingo@540:
ingo@540: for (ZoomHandler handler: handlers) {
ingo@540: handler.onZoom(event);
ingo@540: }
ingo@540: }
ingo@540: }
ingo@540: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :