gwt.material.design.addins.client.popupmenu.MaterialPopupMenu.java Source code

Java tutorial

Introduction

Here is the source code for gwt.material.design.addins.client.popupmenu.MaterialPopupMenu.java

Source

/*
 * #%L
 * GwtMaterial
 * %%
 * Copyright (C) 2015 - 2017 GwtMaterialDesign
 * %%
 * Licensed 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.
 * #L%
 */
package gwt.material.design.addins.client.popupmenu;

import com.google.gwt.core.client.Scheduler;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.logical.shared.*;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.user.client.DOM;
import gwt.material.design.addins.client.MaterialAddins;
import gwt.material.design.addins.client.base.constants.AddinsCssName;
import gwt.material.design.client.MaterialDesignBase;
import gwt.material.design.client.base.JsLoader;
import gwt.material.design.client.constants.CssName;
import gwt.material.design.client.ui.html.UnorderedList;
import gwt.material.design.jquery.client.api.JQueryElement;

import static gwt.material.design.jquery.client.api.JQuery.$;

/**
 * Popup Menu.
 *
 * @author Mark Kevin
 * @author Ben Dol
 */
public class MaterialPopupMenu extends UnorderedList implements JsLoader, HasSelectionHandlers<Element>,
        HasOpenHandlers<MaterialPopupMenu>, HasCloseHandlers<MaterialPopupMenu> {

    static {
        if (MaterialAddins.isDebug()) {
            MaterialDesignBase.injectCss(MaterialPopupMenuDebugClientBundle.INSTANCE.menuCssDebug());
        } else {
            MaterialDesignBase.injectCss(MaterialPopupMenuClientBundle.INSTANCE.menuCss());
        }
    }

    private int popupX;
    private int popupY;
    private String id;
    private Object selected;

    public MaterialPopupMenu() {
        id = DOM.createUniqueId();
        setInitialClasses(AddinsCssName.POPUP_MENU, AddinsCssName.MENU_BAR, CssName.Z_DEPTH_3);
    }

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

        load();
    }

    @Override
    public void load() {
        $(this).attr("tabindex", "0");
        $(this).on("blur", e -> {
            close();
            return true;
        });

        $("*").on("scroll." + id, e -> {
            close();
            return true;
        });

        initializeSelectionEvent();

        close();
    }

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

        unload();
    }

    @Override
    public void unload() {
        $(".popup-menu li").off("mouseleave");
        $(".popup-menu li").off("click");
        $(".popup-menu li").off("mouseover");
        $(this).off("." + id);
        $("*").off("." + id);
    }

    @Override
    public void reload() {
        unload();
        load();
    }

    private void initializeSelectionEvent() {
        // Initialization of Selection event
        $(".popup-menu li").on("click", e -> {
            e.stopPropagation();
            SelectionEvent.fire(MaterialPopupMenu.this, $(e.getCurrentTarget()).asElement());
            $(this).hide();
            return true;
        });

        // Check if the dropdown is not visible anymore into it's container either left / bottom side
        $(".popup-menu li").on("mouseover", (e, param1) -> {
            JQueryElement item = $(e.getCurrentTarget()).find("a");
            if (item.attr("data-activates") != null) {
                JQueryElement dp = $("#" + item.attr("data-activates"));

                double dpWidth = dp.width();
                double dpLeft = dp.offset().left;
                double conWidth = body().width();

                double dpHeight = 200;
                double dpTop = dp.offset().top;
                double conHeight = body().height();

                if (dpWidth + dpLeft > conWidth) {
                    dp.addClass(AddinsCssName.EDGE_LEFT);
                }

                if (dpHeight + dpTop > conHeight) {
                    dp.addClass(AddinsCssName.EDGE_BOTTOM);
                }
            }
            return true;
        });

        $(".popup-menu li").on("mouseleave", (e, param) -> {
            JQueryElement item = $(e.getCurrentTarget()).find("a");
            if (item.attr("data-activates") != null) {
                JQueryElement dp = $("#" + item.attr("data-activates"));
                dp.removeClass(AddinsCssName.EDGE_LEFT);
                dp.removeClass(AddinsCssName.EDGE_BOTTOM);
            }
            return true;
        });
    }

    /**
     * Set the popup position of the context menu
     *
     * @param popupX window x position
     * @param popupY window y position
     */
    public void setPopupPosition(int popupX, int popupY) {
        // Will check if the popup is out of container
        this.popupX = popupX;
        this.popupY = popupY;
        setLeft(popupX);
        setTop(popupY);
    }

    @Override
    public HandlerRegistration addSelectionHandler(SelectionHandler<Element> selectionHandler) {
        return addHandler(selectionHandler, SelectionEvent.getType());
    }

    public void open() {
        setVisible(true);
        Scheduler.get().scheduleDeferred(() -> setFocus(true));

        // Check if dropdown is out of the container (Left)
        if ($(this).width() + $(this).offset().left > body().width()) {
            setLeft(body().width() - $(this).width());
        }
        OpenEvent.fire(this, this);
    }

    public void close() {
        setVisible(false);
        CloseEvent.fire(this, this);
    }

    public Object getSelected() {
        return selected;
    }

    public void setSelected(Object selected) {
        this.selected = selected;
    }

    @Override
    public HandlerRegistration addCloseHandler(CloseHandler<MaterialPopupMenu> closeHandler) {
        return addHandler(new CloseHandler<MaterialPopupMenu>() {
            @Override
            public void onClose(CloseEvent<MaterialPopupMenu> closeEvent) {
                if (isEnabled()) {
                    closeHandler.onClose(closeEvent);
                }
            }
        }, CloseEvent.getType());
    }

    @Override
    public HandlerRegistration addOpenHandler(OpenHandler<MaterialPopupMenu> openHandler) {
        return addHandler(new OpenHandler<MaterialPopupMenu>() {
            @Override
            public void onOpen(OpenEvent<MaterialPopupMenu> openEvent) {
                if (isEnabled()) {
                    openHandler.onOpen(openEvent);
                }
            }
        }, OpenEvent.getType());
    }

    public int getPopupX() {
        return popupX;
    }

    public int getPopupY() {
        return popupY;
    }
}