Package org.gwtoolbox.widget.client.button.version2

Source Code of org.gwtoolbox.widget.client.button.version2.Button

package org.gwtoolbox.widget.client.button.version2;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Style;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.event.dom.client.MouseUpEvent;
import com.google.gwt.event.dom.client.MouseUpHandler;
import com.google.gwt.i18n.client.LocaleInfo;
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.FocusWidget;
import com.google.gwt.user.client.ui.Image;
import org.gwtoolbox.commons.ui.client.event.CompoundHandlerRegistration;
import org.gwtoolbox.widget.client.panel.LayoutUtils;
import org.gwtoolbox.widget.client.support.CssFloat;

/**
* A button component that triggers an action when a user clicks on it.
* <p/>
* <p></p>This button knows a number of faces for different situations. Each face is shown by switching between different
* CSS classes which are appended to the base CSS class "Button".
* <table>
* <tr><th>Face</th><th>Description</th><th>CSS class</th>
* <tr><td>"Up"</td><td>Shown when the user does not press or hover over the button (default face).</td><td>-</td></tr>
* <tr><td>"Down"</td><td>Shown when the user presses and holds the mouse down.</td><td>down</td></tr>
* <tr><td>"Disabled"</td><td>Shown when the button is disabled. See {@link #setEnabled(boolean)}.</td><td>disabled</td></tr>
* <tr><td>"Hover"</td><td>Shown when the user hovers over the button.</td><td>over</td></tr>
* </table>
* <p/>
* <p></p>The entire button is divided into three parts which each use their own CSS class: "left", "center" and "right".
*
* @author Tom van Zummeren
*/
public class Button extends FocusWidget {

    private static final String BASE_CSS_CLASS = "Button";

    private static final String LEFT_SIDE_CSS_CLASS = "Button-left";

    private static final String CENTER_CSS_CLASS = "Button-center";

    private static final String RIGHT_SIDE_CSS_CLASS = "Button-right";

    private static final String FACE_HOVER_CSS_CLASS = "hover";

    private static final String FACE_DOWN_CSS_CLASS = "down";

    private static final String DISABLED_CSS_CLASS = "disabled";

    private CompoundHandlerRegistration internalHandlerRegistration;

    private Impl impl = GWT.create(Impl.class);

    private Element center;

    private Element currentImage;
    private Element caption;

    /**
     * Constructs a new {@code Button} which only shows a text without an icon.
     *
     * @param captionText text to show on the button
     */
    public Button(String captionText) {
        this(captionText, (Image) null);
    }

    /**
     * Constructs a new {@code Button} which only shows an icon.
     *
     * @param icon icon image to display left of the caption (may be {@code null})
     */
    public Button(Image icon) {
        this(null, icon);
    }

    /**
     * Constructs a new {@code Button} which shows a text with an icon left of it.
     *
     * @param captionText text to show on the button
     * @param icon        icon image to display left of the caption (may be {@code null})
     */
    public Button(String captionText, Image icon) {
        this(captionText, icon, null);
    }

    /**
     * Constructs a new {@code Button} with a click handler showing a text without an icon.
     *
     * @param captionText  text to show on the button
     * @param clickHandler the click clickHandler (may be {@code null})
     */
    public Button(String captionText, ClickHandler clickHandler) {
        this(captionText, null, clickHandler);

    }

    /**
     * Constructs a new {@code Button} with a click handler showing a text without an icon.
     *
     * @param icon         icon image to display left of the caption (may be {@code null})
     * @param clickHandler the click clickHandler (may be {@code null})
     */
    public Button(Image icon, ClickHandler clickHandler) {
        this(null, icon, clickHandler);

    }

    /**
     * Constructs a new {@code Button} with a text, an image and a click handler.
     *
     * @param captionText  text to show on the button
     * @param icon         icon image to display left of the captionText (may be {@code null})
     * @param clickHandler the click clickHandler (may be {@code null})
     */
    public Button(String captionText, Image icon, ClickHandler clickHandler) {
        super(DOM.createElement("div"));
        Element container = getElement();
        // TODO - Tom: Explain in a comment why it's needed to set the line-height when it's already defined in button.css
        DOM.setStyleAttribute(container, "lineHeight", "23px");
        LayoutUtils.setCssFloat(container, LocaleInfo.getCurrentLocale().isRTL() ? CssFloat.RIGHT : CssFloat.LEFT);
        container.setClassName(BASE_CSS_CLASS);

        Element leftSide = DOM.createElement("div");
        container.appendChild(leftSide);
        leftSide.setClassName(LEFT_SIDE_CSS_CLASS);

        center = DOM.createElement("div");
        container.appendChild(center);
        center.setClassName(CENTER_CSS_CLASS);

        caption = DOM.createElement("span");
        center.appendChild(caption);

        Element rightSide = DOM.createElement("div");
        container.appendChild(rightSide);
        rightSide.setClassName(RIGHT_SIDE_CSS_CLASS);

        if (clickHandler != null) {
            addClickHandler(clickHandler);
        }
        if (icon != null) {
            setIcon(icon);
        }
        if (captionText != null) {
            setCaption(captionText);
        }
    }

    /**
     * Changes the caption this button is showing.
     *
     * @param captionText new caption text to show
     */
    public void setCaption(String captionText) {
        caption.setInnerText(captionText);
        if (currentImage != null) {
            DOM.setStyleAttribute(caption, "marginLeft", "5px");
        }
    }

    /**
     * Sets the icon image to display to the left of the caption text.
     *
     * @param icon icon image to set ({@code null} to remove current icon)
     */
    public void setIcon(Image icon) {
        if (currentImage != null) {
            center.removeChild(currentImage);
        }
        if (icon == null) {
            return;
        }
        int iconHeight = icon.getHeight();
        int margin = (23 - iconHeight) / 2;

        currentImage = icon.getElement();
        DOM.setStyleAttribute(currentImage, "marginTop", margin + "px");

        center.insertFirst(currentImage);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void onLoad() {
        internalHandlerRegistration = new CompoundHandlerRegistration();

        // Change to the "hover" face when mouse hovers over the button
        internalHandlerRegistration.addRegistration(addMouseOverHandler(new MouseOverHandler() {
            public void onMouseOver(MouseOverEvent event) {
                Button.this.addStyleDependentName(FACE_HOVER_CSS_CLASS);
            }
        }));

        // Remove the "hover" face when mouse hovers out of the button
        internalHandlerRegistration.addRegistration(addMouseOutHandler(new MouseOutHandler() {
            public void onMouseOut(MouseOutEvent event) {
                Button.this.removeStyleDependentName(FACE_HOVER_CSS_CLASS);
                Button.this.removeStyleDependentName(FACE_DOWN_CSS_CLASS);
            }
        }));

        // Change to the "down" face when the button is pressed
        internalHandlerRegistration.addRegistration(addMouseDownHandler(new MouseDownHandler() {
            public void onMouseDown(MouseDownEvent event) {
                Button.this.addStyleDependentName(FACE_DOWN_CSS_CLASS);
            }
        }));

        // Remove the "down" face when the button is released
        internalHandlerRegistration.addRegistration(addMouseUpHandler(new MouseUpHandler() {
            public void onMouseUp(MouseUpEvent event) {
                Button.this.removeStyleDependentName(FACE_DOWN_CSS_CLASS);
            }
        }));
        impl.disableTextSelection(getElement());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void onUnload() {
        super.onUnload();
        if (internalHandlerRegistration != null) {
            internalHandlerRegistration.removeHandler();
            internalHandlerRegistration = null;
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void onBrowserEvent(Event event) {
        // Events should only be handled when the button is enabled.
        if (isEnabled()) {
            super.onBrowserEvent(event);
        }
    }

    /**
     * Sets the width of this button as a string. This is the same string you would set on a regular HTML element.
     * <p></p>Examples: "100px", "50em", "75pt"
     */
    @Override
    public void setWidth(String width) {
        // Sets the width on the style property of the element, instead of the width attribute like the super does.
        getElement().getStyle().setProperty("width", width);
    }

    /**
     * @see Style#setWidth(double, com.google.gwt.dom.client.Style.Unit)
     */
    public void setWidth(double value, Style.Unit unit) {
        getElement().getStyle().setWidth(value, unit);
    }

    /**
     * Sets the width of this button in pixels.
     *
     * @param pixels amount of pixels to set the width on
     * @see #setWidth(double, com.google.gwt.dom.client.Style.Unit)
     */
    public void setWidthInPixels(double pixels) {
        setWidth(pixels, Style.Unit.PX);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void setEnabled(boolean enabled) {
        super.setEnabled(enabled);

        if (enabled) {
            // Remove the disabled face's CSS class
            removeStyleDependentName(DISABLED_CSS_CLASS);
        } else {
            // Remove any existing faces and add the disabled face's CSS class
            setStyleName(BASE_CSS_CLASS);
            addStyleDependentName(DISABLED_CSS_CLASS);
        }
    }

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

    private static class Impl {

        public void disableTextSelection(Element element) {
        }
    }

    private static class ImplIE extends Impl {

        /**
         * Disables selecting text on this button when using Internet Explorer.
         *
         * @param element the element to perform the 'IE fix' on
         */
        @Override
        public native void disableTextSelection(Element element) /*-{
            element.onselectstart = function() { return false; };
        }-*/;
    }
}
TOP

Related Classes of org.gwtoolbox.widget.client.button.version2.Button

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.