org.waveprotocol.wave.client.widget.button.icon.IconButtonTemplate.java Source code

Java tutorial

Introduction

Here is the source code for org.waveprotocol.wave.client.widget.button.icon.IconButtonTemplate.java

Source

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.waveprotocol.wave.client.widget.button.icon;

import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.StyleInjector;
import com.google.gwt.event.dom.client.ClickEvent;
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.resources.client.ClientBundle;
import com.google.gwt.resources.client.CssResource;
import com.google.gwt.resources.client.CssResource.Shared;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.resources.client.ImageResource.ImageOptions;
import com.google.gwt.uibinder.client.UiConstructor;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Label;

import org.waveprotocol.wave.client.common.webdriver.DebugClassHelper;
import org.waveprotocol.wave.client.widget.button.ButtonDisplay;
import org.waveprotocol.wave.client.widget.button.MouseListener;
import org.waveprotocol.wave.client.widget.button.StyleAxis;

/**
 * Template for a button that is implemented as a single image with no text.
 *
 */
public class IconButtonTemplate extends Composite implements ButtonDisplay, ClickHandler, MouseOverHandler,
        MouseOutHandler, MouseUpHandler, MouseDownHandler {
    /**
     * Separate out the down/hover styling, to allow buttons from outside
     *   this template to be used for icon buttons.
     */
    @Shared
    public interface ButtonStateCss extends CssResource {
        /* Normal state assumed to be an empty modifier */
        String down();

        String hover();

        String disabled();
    }

    /**
     * This is part 1 of the Resource bundle.  The bundle is split
     * into 2 parts to avoid crashing chrome.
     */
    public interface Resources extends ClientBundle {
        // Panel icons.
        @Source("panel-minimize.png")
        @ImageOptions(flipRtl = true)
        ImageResource panelMinimize();

        @Source("panel-minimize-down.png")
        @ImageOptions(flipRtl = true)
        ImageResource panelMinimizeDown();

        @Source("panel-minimize-hover.png")
        @ImageOptions(flipRtl = true)
        ImageResource panelMinimizeHover();

        @Source("panel-maximize.png")
        @ImageOptions(flipRtl = true)
        ImageResource panelMaximize();

        @Source("panel-maximize-down.png")
        @ImageOptions(flipRtl = true)
        ImageResource panelMaximizeDown();

        @Source("panel-maximize-hover.png")
        @ImageOptions(flipRtl = true)
        ImageResource panelMaximizeHover();

        @Source("panel-restore.png")
        @ImageOptions(flipRtl = true)
        ImageResource panelRestore();

        @Source("panel-restore-down.png")
        @ImageOptions(flipRtl = true)
        ImageResource panelRestoreDown();

        @Source("panel-restore-hover.png")
        @ImageOptions(flipRtl = true)
        ImageResource panelRestoreHover();

        @Source("panel-close.png")
        @ImageOptions(flipRtl = true)
        ImageResource panelClose();

        @Source("panel-close-down.png")
        @ImageOptions(flipRtl = true)
        ImageResource panelCloseDown();

        @Source("panel-close-hover.png")
        @ImageOptions(flipRtl = true)
        ImageResource panelCloseHover();

        @Source("IconButtonTemplate.css")
        Css css();

        interface Css extends ButtonStateCss {
            String panelMinimize();

            String panelMaximize();

            String panelRestore();

            String panelClose();
        }
    }

    /**
     * This is part 2 of the Resource bundle.  The bundle is split
     * into 2 parts to avoid crashing chrome.
     */
    public interface Resources1 extends ClientBundle {
        @Source("blue-plus.png")
        @ImageOptions(flipRtl = true)
        ImageResource bluePlus();

        @Source("folder-closed.png")
        @ImageOptions(flipRtl = true)
        ImageResource folderClosed();

        @Source("folder-open.png")
        @ImageOptions(flipRtl = true)
        ImageResource folderOpen();

        @Source("alert_close_button.png")
        @ImageOptions(flipRtl = true)
        ImageResource alertClose();

        @Source("alert_close_button_down.png")
        @ImageOptions(flipRtl = true)
        ImageResource alertCloseDown();

        @Source("alert_close_button_hover.png")
        @ImageOptions(flipRtl = true)
        ImageResource alertCloseHover();

        @Source("popup-button.png")
        @ImageOptions(flipRtl = true)
        ImageResource popupButtonImage();

        @Source("view_switcher_feed.png")
        @ImageOptions(flipRtl = true)
        ImageResource viewSwitcherFeed();

        @Source("view_switcher_feed_down.png")
        @ImageOptions(flipRtl = true)
        ImageResource viewSwitcherFeedDown();

        @Source("view_switcher_single.png")
        @ImageOptions(flipRtl = true)
        ImageResource viewSwitcherSingle();

        @Source("view_switcher_single_down.png")
        @ImageOptions(flipRtl = true)
        ImageResource viewSwitcherSingleDown();

        @Source("view_switcher_avatar.png")
        @ImageOptions(flipRtl = true)
        ImageResource viewSwitcherAvatar();

        @Source("view_switcher_avatar_down.png")
        @ImageOptions(flipRtl = true)
        ImageResource viewSwitcherAvatarDown();

        @Source("spelly-dropdown.png")
        @ImageOptions(flipRtl = true)
        ImageResource spellyDropdown();

        @Source("button_digest_next.png")
        @ImageOptions(flipRtl = true)
        ImageResource nextDigestPage();

        @Source("button_digest_next_down.png")
        @ImageOptions(flipRtl = true)
        ImageResource nextDigestPageDown();

        @Source("button_digest_prev.png")
        @ImageOptions(flipRtl = true)
        ImageResource previousDigestPage();

        @Source("button_digest_prev_down.png")
        @ImageOptions(flipRtl = true)
        ImageResource previousDigestPageDown();

        @Source("lightbulb.png")
        @ImageOptions(flipRtl = true)
        ImageResource lightbulb();

        @Source("add.png")
        @ImageOptions(flipRtl = true)
        ImageResource add();

        @Source("addDown.png")
        @ImageOptions(flipRtl = true)
        ImageResource addDown();

        @Source("add-big.png")
        @ImageOptions(flipRtl = true)
        ImageResource addBig();

        @Source("add-big-down.png")
        @ImageOptions(flipRtl = true)
        ImageResource addBigDown();

        @Source("add_small.png")
        @ImageOptions(flipRtl = true)
        ImageResource addSmall();

        @Source("add_small_down.png")
        @ImageOptions(flipRtl = true)
        ImageResource addSmallDown();

        @Source("remove_tag_button.png")
        @ImageOptions(flipRtl = true)
        ImageResource removeTag();

        @Source("remove_tag_button_hover.png")
        @ImageOptions(flipRtl = true)
        ImageResource removeTagHover();

        @Source("split_button_dropdown.png")
        @ImageOptions(flipRtl = true)
        ImageResource splitButtonDropdown();

        @Source("split_button_dropdown_down.png")
        @ImageOptions(flipRtl = true)
        ImageResource splitButtonDropdownDown();

        @Source("IconButtonTemplate1.css")
        Css1 css();

        interface Css1 extends ButtonStateCss {
            String bluePlus();

            String folderExpand();

            String alertClose();

            String viewSwitcherAvatar();

            String viewSwitcherSingle();

            String nextDigestPage();

            String previousDigestPage();

            String spellyDropdown();

            String lightbulb();

            String removeTag();

            String popupButton();

            String viewSwitcherFeed();

            String splitButtonDropdown();

            String add();

            String addBig();

            String addSmall();

            String cursorDefault();

            String cursorPointer();
        }
    }

    /**
     * The styles that this kind of button can have.
     *
     */
    public static enum IconButtonStyle {
        BLUE_PLUS, PANEL_MINIMIZE, PANEL_RESTORE, PANEL_MAXIMIZE, PANEL_CLOSE, PLUS_MINUS, POPUP_MENU, ALERT_CLOSE, VIEW_SWITCHER_AVATAR, VIEW_SWITCHER_FEED, VIEW_SWITCHER_SINGLE, NEXT_DIGEST_PAGE, PREVIOUS_DIGEST_PAGE, SPELLY_DROPDOWN, LIGHTBULB, ADD, ADD_BIG, ADD_SMALL, REMOVE_TAG, SPLIT_BUTTON_DROPDOWN
    }

    /** The singleton instance of our resources. */
    private static final Resources RESOURCES = GWT.create(Resources.class);
    /** The singleton instance of our resources. */
    private static final Resources1 RESOURCES1 = GWT.create(Resources1.class);

    /**
     * The controller of this UI widget.
     */
    private MouseListener mouseListener;

    /**
     * The CSS class that describes the current state of the button.
     */
    private StyleAxis buttonStateClassName;

    /**
     * The CSS class that describes the style of the icon.
     */
    private StyleAxis iconStyleClassName;

    /**
     * The last debug class name set relating to the state.
     */
    private String stateDebugClassName = "";

    /**
     * The CSS class that describes the cursor for this icon.
     */
    private StyleAxis cursorStyleClassName;

    @UiField
    HTMLPanel icon;

    static {
        StyleInjector.inject(RESOURCES.css().getText(), true);
        StyleInjector.inject(RESOURCES1.css().getText(), true);
    }

    /**
     * @param style Dictates what the button should look like.
     * @param tooltip The tooltip for this button.
     */
    public IconButtonTemplate(IconButtonStyle style, String tooltip) {
        this();
        init(style, tooltip);
    }

    @UiConstructor
    public IconButtonTemplate() {
        Label label = new Label();
        initWidget(label);
        label.addClickHandler(this);
        label.addMouseOverHandler(this);
        label.addMouseOutHandler(this);
        label.addMouseUpHandler(this);
        label.addMouseDownHandler(this);
    }

    /**
     * Initialize the state of this widget.
     *
     * @param style Dictates what the button should look like.
     * @param tooltip The tooltip for this button.
     */
    public void init(IconButtonStyle style, String tooltip) {
        buttonStateClassName = new StyleAxis(getElement());
        iconStyleClassName = new StyleAxis(getElement());
        cursorStyleClassName = new StyleAxis(getElement());
        cursorStyleClassName.setStyle(RESOURCES1.css().cursorPointer());
        setStyle(style);
        setTitle(tooltip);
    }

    /**
     * TODO(user) to make the style final once UiBinder is in.
     *
     * @param style The {@link IconButtonStyle} this button should adopt.
     */
    public void setStyle(IconButtonStyle style) {
        String styleName = null;
        switch (style) {
        case PANEL_CLOSE:
            styleName = RESOURCES.css().panelClose();
            DebugClassHelper.addDebugClass(this, "close");
            break;
        case PANEL_MAXIMIZE:
            styleName = RESOURCES.css().panelMaximize();
            DebugClassHelper.addDebugClass(this, "maximise");
            break;
        case PANEL_MINIMIZE:
            styleName = RESOURCES.css().panelMinimize();
            DebugClassHelper.addDebugClass(this, "minimise");
            break;
        case PANEL_RESTORE:
            styleName = RESOURCES.css().panelRestore();
            DebugClassHelper.addDebugClass(this, "restore");
            break;
        case PLUS_MINUS:
            styleName = RESOURCES1.css().folderExpand();
            break;
        case POPUP_MENU:
            styleName = RESOURCES1.css().popupButton();
            break;
        case ALERT_CLOSE:
            styleName = RESOURCES1.css().alertClose();
            break;
        case BLUE_PLUS:
            styleName = RESOURCES1.css().bluePlus();
            break;
        case VIEW_SWITCHER_AVATAR:
            styleName = RESOURCES1.css().viewSwitcherAvatar();
            break;
        case VIEW_SWITCHER_FEED:
            styleName = RESOURCES1.css().viewSwitcherFeed();
            break;
        case VIEW_SWITCHER_SINGLE:
            styleName = RESOURCES1.css().viewSwitcherSingle();
            break;
        case SPELLY_DROPDOWN:
            styleName = RESOURCES1.css().spellyDropdown();
            break;
        case NEXT_DIGEST_PAGE:
            styleName = RESOURCES1.css().nextDigestPage();
            break;
        case PREVIOUS_DIGEST_PAGE:
            styleName = RESOURCES1.css().previousDigestPage();
            break;
        case LIGHTBULB:
            styleName = RESOURCES1.css().lightbulb();
            break;
        case REMOVE_TAG:
            styleName = RESOURCES1.css().removeTag();
            break;
        case SPLIT_BUTTON_DROPDOWN:
            styleName = RESOURCES1.css().splitButtonDropdown();
            break;
        case ADD:
            styleName = RESOURCES1.css().add();
            break;
        case ADD_BIG:
            styleName = RESOURCES1.css().addBig();
            break;
        case ADD_SMALL:
            styleName = RESOURCES1.css().addSmall();
            break;
        }
        iconStyleClassName.setStyle(styleName);
    }

    /** {@inheritDoc} */
    public void setState(ButtonState state) {
        String styleName = null;
        String newStateDebugClassName = "";
        switch (state) {
        case DISABLED:
            newStateDebugClassName = "disabled";
            styleName = internalStateCss.disabled();
            cursorStyleClassName.setStyle(RESOURCES1.css().cursorDefault());
            break;
        case DOWN:
            newStateDebugClassName = "down";
            styleName = internalStateCss.down();
            break;
        case HOVER:
            newStateDebugClassName = "hover";
            styleName = internalStateCss.hover();
            break;
        case NORMAL:
            newStateDebugClassName = "normal";
            styleName = null;
            break;
        }
        DebugClassHelper.replaceDebugClass(getElement(), "ibts_" + stateDebugClassName,
                "ibts_" + newStateDebugClassName);
        stateDebugClassName = newStateDebugClassName;
        buttonStateClassName.setStyle(styleName);
    }

    /** {@inheritDoc} */
    public void setUiListener(MouseListener mouseListener) {
        this.mouseListener = mouseListener;
    }

    @Override
    public void setTooltip(String tooltip) {
        setTitle(tooltip);
    }

    @Override
    public void setText(String text) {
        ((Label) getWidget()).setText(text);
    }

    @Override
    protected void onDetach() {
        super.onDetach();
        if (mouseListener != null) {
            mouseListener.onMouseLeave();
        }
    }

    /**
     * Opens up the ability to use a style (= icon) not within the control of this template
     * Requires using style sheet with .down and .hover styles
     */
    private ButtonStateCss internalStateCss = RESOURCES.css(); // by default, do the same as always

    /**
     * Creates a new {@link IconButtonTemplate} with the given style and logic,
     *   taking the style name directly
     *
     * @param styleName Dictates what the button should look like.
     * @param tooltip The tooltip for this button.
     * @return A new {@link IconButtonTemplate} that behaves and looks as
     *         described.
     */
    public static IconButtonTemplate createDirect(String styleName, String tooltip, ButtonStateCss stateCss) {
        IconButtonTemplate template = new IconButtonTemplate();
        template.initDirect(styleName, tooltip, stateCss);
        return template;
    }

    /**
     * Initialize the state of this widget, taking the style name directly
     *
     * @param styleName Dictates what the button should look like.
     * @param tooltip The tooltip for this button.
     */
    private void initDirect(String styleName, String tooltip, ButtonStateCss stateCss) {
        internalStateCss = stateCss;
        buttonStateClassName = new StyleAxis(getElement());
        iconStyleClassName = new StyleAxis(getElement());
        iconStyleClassName.setStyle(styleName);
        setTitle(tooltip);
    }

    @Override
    public void onClick(ClickEvent event) {
        mouseListener.onClick();
        event.stopPropagation();
    }

    @Override
    public void onMouseOver(MouseOverEvent event) {
        mouseListener.onMouseEnter();
    }

    @Override
    public void onMouseOut(MouseOutEvent event) {
        mouseListener.onMouseLeave();
    }

    @Override
    public void onMouseUp(MouseUpEvent event) {
        mouseListener.onMouseUp();
    }

    @Override
    public void onMouseDown(MouseDownEvent event) {
        mouseListener.onMouseDown();
    }
}