ImageToggleButton.java :  » GWT » gwtoolbox » org » gwtoolbox » widget » client » button » Java Open Source

Java Open Source » GWT » gwtoolbox 
gwtoolbox » org » gwtoolbox » widget » client » button » ImageToggleButton.java
package org.gwtoolbox.widget.client.button;

import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.*;
import com.google.gwt.event.shared.HandlerRegistration;
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.ui.Composite;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.SimplePanel;
import org.gwtoolbox.widget.client.event.custom.HasToggleHandlers;
import org.gwtoolbox.widget.client.event.custom.ToggleEvent;
import org.gwtoolbox.widget.client.event.custom.ToggleHandler;

import java.util.HashMap;
import java.util.Map;

/**
 * @author Uri Boness
 */
public class ImageToggleButton extends Composite implements HasToggleHandlers {

    private final static int UP = 1;
    private final static int DOWN = 2;
    private final static int HOVERING = 4;
    private final static int DISABLED = 8;

    private Map<Integer, Face> faces = new HashMap<Integer, Face>();

    private boolean enabled = true;
    private boolean hovering;
    private boolean down;
    private boolean isCapturing;

    private String group;
    private final static Map<String, Group> groupByName = new HashMap<String, Group>();

    private Face currentFace;
    private SimplePanel imagePane;

    private HandlerRegistration[] internalHandlerRegistrations;

    public ImageToggleButton(Image image) {
        initFaces(image);

        imagePane = new SimplePanel();
        DOM.setStyleAttribute(imagePane.getElement(), "position", "relative");

        initWidget(imagePane);
        imagePane.setStylePrimaryName("ImageToggleButton");
        setCurrentFace(UP);
    }

    @Override
    public void setSize(String width, String height) {
        throw new UnsupportedOperationException("A ToolButton as a fixed size of 25 x 25 pixels");
    }

    public HandlerRegistration addToggleHandler(ToggleHandler handler) {
        return addHandler(handler, ToggleEvent.getType());
    }

    public boolean isEnabled() {
        return enabled;
    }

    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
        updateFace();
    }

    public void toggle() {
        toggle(true);
    }

    public void setDown(boolean down) {
        setState(down, false);
    }

    public boolean isDown() {
        return down;
    }

    public void setGroup(String group) {
        this.group = group;
        if (!groupByName.containsKey(group)) {
            groupByName.put(group, new Group());
        }
    }

    public Face getUpFace() {
        return faces.get(UP);
    }

    public Face getUpHoverFace() {
        return faces.get(UP | HOVERING);
    }

    public Face getUpDisabledFace() {
        return faces.get(UP | DISABLED);
    }

    public Face getUpDisabledHoverFace() {
        return faces.get(UP | HOVERING | DISABLED);
    }

    public Face getDownFace() {
        return faces.get(DOWN);
    }

    public Face getDownHoverFace() {
        return faces.get(DOWN | HOVERING);
    }

    public Face getDownDisabledFace() {
        return faces.get(DOWN | DISABLED);
    }

    public Face getDownDisabledHoverFace() {
        return faces.get(DOWN | DISABLED | HOVERING);
    }

    //================================================ Helper Methods ==================================================

    @Override
    protected void onLoad() {
        super.onLoad();

        internalHandlerRegistrations = new HandlerRegistration[6];

        internalHandlerRegistrations[0] = addDomHandler(new MouseDownHandler() {
            public void onMouseDown(MouseDownEvent event) {
                if (event.getNativeButton() == NativeEvent.BUTTON_LEFT) {
                    DOM.setCapture(getElement());
                    isCapturing = true;
                    // Prevent dragging (on some browsers);
                    event.preventDefault();
                    setCurrentFace(DOWN);
                }
            }
        }, MouseDownEvent.getType());

        internalHandlerRegistrations[1] = addDomHandler(new MouseUpHandler() {
            public void onMouseUp(MouseUpEvent event) {
                if (isCapturing) {
                    isCapturing = false;
                    DOM.releaseCapture(getElement());
                    if (hovering && event.getNativeButton() == NativeEvent.BUTTON_LEFT) {
                        toggle();
                    }
                }
            }
        }, MouseUpEvent.getType());

        internalHandlerRegistrations[2] = addDomHandler(new MouseMoveHandler() {
            public void onMouseMove(MouseMoveEvent event) {
                if (isCapturing) {
                    event.preventDefault();
                }
            }
        }, MouseMoveEvent.getType());

        internalHandlerRegistrations[3] = addDomHandler(new MouseOutHandler() {
            public void onMouseOut(MouseOutEvent event) {
                Element from = event.getNativeEvent().getEventTarget().cast();
                Element to = event.getRelatedTarget().cast();
                if (DOM.isOrHasChild(getElement(), from) && (to == null || !DOM.isOrHasChild(getElement(), to))) {
                    setHovering(false);
                }
            }
        }, MouseOutEvent.getType());

        internalHandlerRegistrations[4] = addDomHandler(new MouseOverHandler() {
            public void onMouseOver(MouseOverEvent event) {
                Element element = event.getNativeEvent().getEventTarget().cast();
                if (DOM.isOrHasChild(getElement(), element)) {
                    setHovering(true);
                }
            }
        }, MouseOverEvent.getType());

        internalHandlerRegistrations[5] = addDomHandler(new LoseCaptureHandler() {
            public void onLoseCapture(LoseCaptureEvent event) {
                cleanupCaptureState();
            }
        }, LoseCaptureEvent.getType());
    }

    @Override
    protected void onUnload() {
        super.onUnload();
        for (HandlerRegistration registration : internalHandlerRegistrations) {
            registration.removeHandler();
        }
        internalHandlerRegistrations = null;
    }

    @Override
    public void onBrowserEvent(Event event) {
        if (isEnabled()) {
            super.onBrowserEvent(event);
        }
    }

    private void cleanupCaptureState() {
        if (isCapturing) {
            DOM.releaseCapture(getElement());
            isCapturing = false;
        }
    }

    private void toggle(boolean fireEvent) {
        setState(!isDown(), fireEvent);
    }

    private void setState(boolean down, boolean fireEvent) {
        this.down = down;
        updateFace();
        if (down && group != null) {
            groupByName.get(group).handleClicked(this);
        }
        if (fireEvent) {
            ToggleEvent.fire(this, down);
        }
    }

    private void initFaces(Image up) {
        Face upFace = new Face("", up);
        faces.put(UP, upFace);
        faces.put(UP | HOVERING, new Face("hover", upFace));
        faces.put(UP | DISABLED, new Face("disabled", upFace));
        faces.put(UP | DISABLED | HOVERING, new Face("disabled-hover", upFace));
        Face downFace = new Face("down", upFace);
        faces.put(DOWN, downFace);
        faces.put(DOWN | HOVERING, new Face("down-hover", downFace));
        faces.put(DOWN | DISABLED, new Face("down-disabled", downFace));
        faces.put(DOWN | DISABLED | HOVERING, new Face("down-disabled-hover", downFace));
    }

    private void updateFace() {
        if (!down && !hovering && enabled) {    // up
            setCurrentFace(UP);
            return;
        }
        if (!down && hovering && enabled) {     // up hovering
            setCurrentFace(UP | HOVERING);
            return;
        }
        if (!down && !hovering && !enabled) {   // up disabled
            setCurrentFace(UP | DISABLED);
            return;
        }
        if (!down && hovering && !enabled) {    // up disabled hovering
            setCurrentFace(UP | DISABLED | HOVERING);
            return;
        }
        if (down && !hovering && enabled) {     // down
            setCurrentFace(DOWN);
            return;
        }
        if (down && hovering && enabled) {      // down hovering
            setCurrentFace(DOWN | HOVERING);
        }
        if (down && !hovering && !enabled) {     // down diabled
            setCurrentFace(DOWN | DISABLED);
            return;
        }
        if (down && hovering && !enabled) {     // down diabled hovering
            setCurrentFace(DOWN | DISABLED);
            return;
        }
    }

    private void setCurrentFace(int faceType) {
        Face face = faces.get(faceType);
        setCurrentFace(face);
    }

    private void setCurrentFace(Face face) {
        if (currentFace != null) {
            imagePane.removeStyleDependentName(currentFace.getKey());
        }
        currentFace = face;
        Image image = face.getImage();
        setWidth((image.getWidth() + 4) + "px");
        setHeight((image.getHeight() + 4) + "px");

        int left = 2;
        int top = 2;
        imagePane.setWidget(face.getImage());
        DOM.setStyleAttribute(image.getElement(), "position", "relative");
        DOM.setStyleAttribute(image.getElement(), "left", left + "px");
        DOM.setStyleAttribute(image.getElement(), "top", top + "px");
        String key = currentFace.getKey();
        if (key.length() != 0) {
            imagePane.addStyleDependentName(key);
        }
    }

    private void setHovering(boolean hovering) {
        this.hovering = hovering;
        updateFace();
    }


    //================================================= Inner Classes ==================================================

    public class Face {

        private String key;
        private Image image;
        private Face fallback;

        private Face(String key, Face fallback) {
            this(key, null, fallback);
        }

        private Face(String key, Image image) {
            this(key, image, null);
        }

        private Face(String key, Image image, Face fallback) {
            this.key = key;
            this.image = image;
            this.fallback = fallback;
        }

        public void setImage(Image image) {
            this.image = image;
        }

        public Image getImage() {
            if (image != null) {
                return image;
            }
            if (fallback != null) {
                return fallback.getImage();
            }
            return null;
        }

        public String getKey() {
            return key;
        }
    }

    private static class Group {

        private ImageToggleButton currentButton;

        public void handleClicked(ImageToggleButton button) {
            if (currentButton != null) {
                currentButton.setDown(false);
            }
            currentButton = button;
        }
    }
}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.