view flys-client/src/main/java/de/intevation/flys/client/client/ui/chart/ZoomboxControl.java @ 541:ed29599e06e5

Added the ChartOutputTab as ZoomHandler for the ZoomboxControl - no zooming is done yet. flys-client/trunk@2041 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Ingo Weinzierl <ingo.weinzierl@intevation.de>
date Wed, 01 Jun 2011 14:13:29 +0000
parents a866cdf1ca40
children 9c2cf4811a7d
line wrap: on
line source
package de.intevation.flys.client.client.ui.chart;

import java.util.ArrayList;
import java.util.List;

import com.smartgwt.client.types.Positioning;
import com.smartgwt.client.types.SelectionType;
import com.smartgwt.client.widgets.Button;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.events.MouseDownEvent;
import com.smartgwt.client.widgets.events.MouseDownHandler;
import com.smartgwt.client.widgets.events.MouseMoveEvent;
import com.smartgwt.client.widgets.events.MouseMoveHandler;
import com.smartgwt.client.widgets.events.MouseUpEvent;
import com.smartgwt.client.widgets.events.MouseUpHandler;

import de.intevation.flys.client.client.event.HasZoomHandlers;
import de.intevation.flys.client.client.event.ZoomEvent;
import de.intevation.flys.client.client.event.ZoomHandler;


/**
 * This control observes that panel retrieved by ChartOutputTab.getChartPanel().
 * If activated, a zoombox is drawn. One of the two edges is the position of the
 * mouse down event on the observed panel. The other edge is specified by the
 * current mouse position. If the mouse up event occurs, start and end point
 * relative to the left and upper border of the observed panel is determined and
 * a ZoomEvent is fired.
 *
 * @author <a href="mailto:ingo.weinzierl@intevation.de">Ingo Weinzierl</a>
 */
public class ZoomboxControl
extends      Button
implements   MouseDownHandler, MouseUpHandler, MouseMoveHandler, HasZoomHandlers
{
    protected List<ZoomHandler> handlers;

    protected ChartOutputTab chartTab;

    protected Canvas zoombox;

    protected int[] start;
    protected int[] end;


    public ZoomboxControl(ChartOutputTab chartTab) {
        super("Zoombox");

        this.handlers = new ArrayList<ZoomHandler>();
        this.chartTab = chartTab;
        this.start    = new int[2];
        this.end      = new int[2];
        this.zoombox  = new Canvas();

        initZoombox();

        setActionType(SelectionType.CHECKBOX);
        setSelected(false);

        chartTab.getChartPanel().addMouseDownHandler(this);
        chartTab.getChartPanel().addMouseMoveHandler(this);
        chartTab.getChartPanel().addMouseUpHandler(this);
    }


    /**
     * Initializes the zoombox that is displayed over the observed area. The
     * zoombox has an opaque background. Its height/width and x/y values are
     * determined by the start point (mouse down) and the current mouse
     * position.
     */
    protected void initZoombox() {
        zoombox.setPosition(Positioning.ABSOLUTE);
        zoombox.setBorder("2px solid black");
        zoombox.setOpacity(50);
        zoombox.setWidth(0);
        zoombox.setHeight(0);
    }


    /**
     * Registers a new ZoomHandler that wants to listen to ZoomEvents.
     *
     * @param handler A new ZoomHandler.
     */
    public void addZoomHandler(ZoomHandler handler) {
        if (handler != null) {
            handlers.add(handler);
        }
    }


    /**
     * A mouse down event on the specified area will set the start point for the
     * zoombox.
     *
     * @param event The mouse down event which contains the xy coordinates of
     * the observed area.
     */
    public void onMouseDown(MouseDownEvent event) {
        if (!isSelected()) {
            return;
        }

        start[0] = getRelativeX(event.getX());
        start[1] = getRelativeY(event.getY());

        end[0] = start[0];
        end[1] = start[1];

        chartTab.getChartPanel().addChild(zoombox);

        positionZoombox();
    }


    /**
     * A mouse move event on the specified area will set the end point for the
     * zoombox. If the end point differs from the start point, an opaque box is
     * displayed.
     *
     * @param event The mouse move event which contains the xy coordinates of
     * the observed area.
     */
    public void onMouseMove(MouseMoveEvent event) {
        if (!isSelected()) {
            return;
        }

        end[0] = getRelativeX(event.getX());
        end[1] = getRelativeY(event.getY());

        positionZoombox();
    }


    /**
     * The mouse up event finalizes the zoom operation. It sets the end point
     * for this operation, clears the zoombox and fires a ZoomEvent.
     *
     * @param event The mouse up event which contains the xy coordinates of the
     * observed area.
     */
    public void onMouseUp(MouseUpEvent event) {
        if (!isSelected()) {
            return;
        }

        end[0] = getRelativeX(event.getX());
        end[1] = getRelativeY(event.getY());

        fireZoomEvent();

        clearZoombox();

        chartTab.getChartPanel().removeChild(zoombox);
    }


    /**
     * Returns the X coordinate relative to the left border.
     *
     * @param x The X coordinate relative to the window.
     *
     * @return the X coordinate relative to the left border.
     */
    protected int getRelativeX(int x) {
        return x - chartTab.getChartPanel().getPageLeft();
    }


    /**
     * Returns the Y coordinate relative to the top border.
     *
     * @param y The Y coordinate relative to the window.
     *
     * @return the Y coordinate relative to the top border.
     */
    protected int getRelativeY(int y) {
        return y - chartTab.getChartPanel().getPageTop();
    }


    /**
     * Returns min and max x/y values based on the stored values in <i>start</i>
     * and <i>end</i>.
     *
     * @return an int[] as follows: [xmin, ymin, xmax, ymax].
     */
    protected int[] orderPositions() {
        int xmin = start[0] < end[0] ? start[0] : end[0];
        int ymin = start[1] < end[1] ? start[1] : end[1];

        int xmax = start[0] >= end[0] ? start[0] : end[0];
        int ymax = start[1] >= end[1] ? start[1] : end[1];

        return new int[] { xmin, ymin, xmax, ymax };
    }


    /**
     * Sets the width, height, x and y values of the zoombox.
     */
    protected void positionZoombox() {
        int[] values = orderPositions();

        zoombox.setLeft(values[0]);
        zoombox.setTop(values[1]);
        zoombox.setWidth(values[2] - values[0]);
        zoombox.setHeight(values[3] - values[1]);
    }


    /**
     * Clears the zoombox (set position and size to null).
     */
    protected void clearZoombox() {
        zoombox.setLeft(0);
        zoombox.setTop(0);
        zoombox.setWidth(0);
        zoombox.setHeight(0);
    }


    /**
     * Fires a ZoomEvent to all registered listeners.
     */
    protected void fireZoomEvent() {
        int[] pos = orderPositions();

        ZoomEvent event = new ZoomEvent(pos[0], pos[1], pos[2], pos[3]);

        for (ZoomHandler handler: handlers) {
            handler.onZoom(event);
        }
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :

http://dive4elements.wald.intevation.org