org.workcraft.gwt.imagemap.client.ImageMap.java Source code

Java tutorial

Introduction

Here is the source code for org.workcraft.gwt.imagemap.client.ImageMap.java

Source

/*
This file is part of Intake24.
    
 Crown copyright, 2012, 2013, 2014.
    
This software is licensed under the Open Government Licence 3.0:
    
http://www.nationalarchives.gov.uk/doc/open-government-licence/
*/

package org.workcraft.gwt.imagemap.client;

import org.workcraft.gwt.imagemap.shared.ImageMapDefinition;
import org.workcraft.gwt.imagemap.shared.ImageMapDefinition.Area;
import org.workcraft.gwt.imagemap.shared.Point;

import com.google.gwt.core.shared.GWT;
import com.google.gwt.event.dom.client.BlurEvent;
import com.google.gwt.event.dom.client.BlurHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.FocusEvent;
import com.google.gwt.event.dom.client.FocusHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyDownEvent;
import com.google.gwt.event.dom.client.KeyDownHandler;
import com.google.gwt.event.dom.client.MouseMoveEvent;
import com.google.gwt.event.dom.client.MouseMoveHandler;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.Image;

public class ImageMap extends Composite {
    public static interface ResultHandler {
        public void handleResult(int choice);
    }

    private final ImageMapDefinition definition;
    private final FlowPanel imageDiv;
    private final MouseMoveHandler mouseMoveHandler;
    private final ClickHandler clickHandler;

    Image activeOverlay = null;
    int activeArea = -1;
    int lastActiveArea = -1;
    boolean hasFocus = false;

    private void clearOverlay() {
        if (activeOverlay != null) {
            activeOverlay.removeFromParent();
            activeOverlay = null;
        }
    }

    private void setActiveArea(int index) {
        clearOverlay();

        if (index != -1) {
            final Image overlay = new Image(definition.areas[index].overlayUrl);
            overlay.addStyleName("imagemap-overlay");

            imageDiv.add(overlay);

            overlay.addMouseMoveHandler(mouseMoveHandler);
            overlay.addClickHandler(clickHandler);

            activeOverlay = overlay;

            lastActiveArea = index;
        }

        activeArea = index;
    }

    private void next() {
        if (activeArea != -1) {
            int nextActive = activeArea + 1;
            if (nextActive == definition.areas.length)
                nextActive = 0;
            setActiveArea(nextActive);
        }
    }

    private void prev() {
        if (activeArea != -1) {
            int nextActive = activeArea - 1;
            if (nextActive == -1)
                nextActive = definition.areas.length - 1;
            setActiveArea(nextActive);
        }
    }

    private void prefetchImages() {
        for (Area a : definition.areas) {
            Image.prefetch(a.overlayUrl);
        }
    }

    public ImageMap(final ImageMapDefinition definition, final ResultHandler handler) {
        this.definition = definition;

        imageDiv = new FlowPanel();
        imageDiv.addStyleName("imagemap-container");

        imageDiv.getElement().setTabIndex(1);

        final Image baseImage = new Image(definition.baseImageUrl);
        baseImage.addStyleName("imagemap-base-image");

        imageDiv.add(baseImage);

        mouseMoveHandler = new MouseMoveHandler() {
            @Override
            public void onMouseMove(MouseMoveEvent event) {

                double mouseX = (double) event.getRelativeX(baseImage.getElement()) / baseImage.getOffsetWidth();
                double mouseY = (double) event.getRelativeY(baseImage.getElement()) / baseImage.getOffsetWidth();

                int mouseOverArea = -1;

                for (int i = 0; i < definition.areas.length; i++) {
                    if (definition.areas[i].shape.isInside(new Point(mouseX, mouseY))) {
                        mouseOverArea = i;
                        break;
                    }
                }

                if (mouseOverArea != activeArea) {
                    if (hasFocus && mouseOverArea == -1) {
                        setActiveArea(lastActiveArea);
                    } else
                        setActiveArea(mouseOverArea);
                }
            }
        };

        clickHandler = new ClickHandler() {
            @Override
            public void onClick(ClickEvent event) {
                handler.handleResult(definition.areas[activeArea].id);
            }
        };

        baseImage.addMouseMoveHandler(mouseMoveHandler);

        addDomHandler(new KeyDownHandler() {
            @Override
            public void onKeyDown(KeyDownEvent event) {
                // System.out.println (event.getCharCode());

                if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_ENTER) {
                    handler.handleResult(activeArea);
                }

                if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_LEFT) {
                    prev();
                    event.preventDefault();
                }
                if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_RIGHT) {
                    next();
                    event.preventDefault();
                }
                if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_UP) {
                    next();
                    event.preventDefault();
                }
                if (event.getNativeEvent().getKeyCode() == KeyCodes.KEY_DOWN) {
                    prev();
                    event.preventDefault();
                }
            }
        }, KeyDownEvent.getType());

        addDomHandler(new FocusHandler() {
            @Override
            public void onFocus(FocusEvent event) {
                hasFocus = true;
                if (activeArea == -1)
                    setActiveArea(0);
            }
        }, FocusEvent.getType());

        addDomHandler(new BlurHandler() {
            @Override
            public void onBlur(BlurEvent event) {
                hasFocus = false;
                setActiveArea(-1);
            }
        }, BlurEvent.getType());

        initWidget(imageDiv);

        prefetchImages();
    }

}