com.dianaui.universal.core.client.ui.Popover.java Source code

Java tutorial

Introduction

Here is the source code for com.dianaui.universal.core.client.ui.Popover.java

Source

/*
 * #%L
 * Diana UI Core
 * %%
 * Copyright (C) 2014 Diana UI
 * %%
 * 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 com.dianaui.universal.core.client.ui;

import com.dianaui.universal.core.client.ui.base.HasHover;
import com.dianaui.universal.core.client.ui.base.helper.StyleHelper;
import com.dianaui.universal.core.client.ui.base.modal.ModalWithBackdrop;
import com.dianaui.universal.core.client.ui.constants.ModalBackdrop;
import com.dianaui.universal.core.client.ui.constants.Placement;
import com.dianaui.universal.core.client.ui.constants.Styles;
import com.dianaui.universal.core.client.ui.constants.Trigger;
import com.google.gwt.dom.client.DivElement;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Style;
import com.google.gwt.event.dom.client.*;
import com.google.gwt.event.logical.shared.AttachEvent;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.ui.Widget;
import com.google.web.bindery.event.shared.HandlerRegistration;

/**
 * @author Joshua Godi
 * @author <a href='mailto:donbeave@gmail.com'>Alexey Zhokhov</a>
 */
public class Popover extends ModalWithBackdrop implements HasHover {

    private PopoverHeader header = new PopoverHeader();
    private PopoverBody body = new PopoverBody();

    private Trigger trigger = Trigger.HOVER;
    private int hideDelayMs = 0;
    private int showDelayMs = 0;
    private Widget widget;
    private HandlerRegistration inHandler;
    private HandlerRegistration outHandler;
    private HandlerRegistration detachHandler;

    public Popover() {
        this(null, null);
    }

    public Popover(final Placement placement) {
        this(null, placement);
    }

    public Popover(final String heading) {
        this(heading, null);
    }

    public Popover(final String heading, final Placement placement) {
        removeStyleName(Styles.MODAL);
        addStyleName(Styles.POPOVER);

        setFade(true);
        setBackdrop(ModalBackdrop.FALSE);
        if (placement != null) {
            setPlacement(placement);
        } else {
            setPlacement(Placement.TOP);
        }

        if (heading != null) {
            setHeading(heading);
        }

        super.add(body);

        DivElement arrow = Document.get().createDivElement();
        arrow.setClassName(Styles.ARROW);

        getElement().appendChild(arrow);
    }

    public String getHeading() {
        return header.getText();
    }

    public void setHeading(final String heading) {
        super.insert(header, 0);
        header.setText(heading);
    }

    public PopoverHeader getHeader() {
        return header;
    }

    public PopoverBody getBody() {
        return body;
    }

    public void setPosition(final int left, final int top) {
        getElement().getStyle().setLeft(left, Style.Unit.PX);
        getElement().getStyle().setTop(top, Style.Unit.PX);
    }

    public void bind(final Widget widget) {
        this.widget = widget;

        postSetWidget();
    }

    @Override
    public void add(final Widget w) {
        // User can supply own ModalHeader
        if (w instanceof PopoverHeader) {
            header.removeFromParent();
            header = (PopoverHeader) w;
            super.insert(header, 0);
        } else if (w instanceof PopoverBody) {
            body.removeFromParent();
            body = (PopoverBody) w;
            super.add(body);
        } else {
            body.add(w);
        }
    }

    @Override
    public void insert(final Widget child, final int beforeIndex) {
        throw new UnsupportedOperationException("Popover does not support insert widgets");
    }

    @Override
    public int getWidgetCount() {
        return body.getWidgetCount();
    }

    @Override
    public boolean remove(final Widget w) {
        return body.remove(w);
    }

    @Override
    public boolean remove(final int index) {
        return body.remove(index);
    }

    @Override
    public void clear() {
        body.clear();
    }

    @Override
    public Placement getPlacement() {
        return Placement.fromStyleName(getStyleName());
    }

    @Override
    public void setPlacement(final Placement placement) {
        StyleHelper.addUniqueEnumStyleName(this, Placement.class, placement);
    }

    @Override
    public Trigger getTrigger() {
        return trigger;
    }

    @Override
    public void setTrigger(final Trigger trigger) {
        this.trigger = trigger;
    }

    @Override
    public int getShowDelayMs() {
        return showDelayMs;
    }

    @Override
    public void setShowDelayMs(final int showDelayMs) {
        this.showDelayMs = showDelayMs;
    }

    @Override
    public int getHideDelayMs() {
        return hideDelayMs;
    }

    @Override
    public void setHideDelayMs(final int hideDelayMs) {
        this.hideDelayMs = hideDelayMs;
    }

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

        // positioning
        int left = widget.getAbsoluteLeft();
        int top = widget.getAbsoluteTop();
        Placement placement = getPlacement();

        if (placement == Placement.TOP) {
            top -= getOffsetHeight();

            if (getOffsetWidth() > widget.getOffsetWidth()) {
                left -= (getOffsetWidth() - widget.getOffsetWidth()) / 2;
            } else {
                left += (widget.getOffsetWidth() - getOffsetWidth()) / 2;
            }
        } else if (placement == Placement.BOTTOM) {
            top += widget.getOffsetHeight();

            if (getOffsetWidth() > widget.getOffsetWidth()) {
                left -= (getOffsetWidth() - widget.getOffsetWidth()) / 2;
            } else {
                left += (widget.getOffsetWidth() - getOffsetWidth()) / 2;
            }
        } else if (placement == Placement.LEFT) {
            left -= getOffsetWidth();

            if (getOffsetHeight() > widget.getOffsetHeight()) {
                top -= (getOffsetHeight() - widget.getOffsetHeight()) / 2;
            } else {
                top += (widget.getOffsetHeight() - getOffsetHeight()) / 2;
            }
        } else if (placement == Placement.RIGHT) {
            left += widget.getOffsetWidth();

            if (getOffsetHeight() > widget.getOffsetHeight()) {
                top -= (getOffsetHeight() - widget.getOffsetHeight()) / 2;
            } else {
                top += (widget.getOffsetHeight() - getOffsetHeight()) / 2;
            }
        }

        setPosition(left, top);
    }

    private void postSetWidget() {
        if (widget != null) {
            widget.addAttachHandler(new AttachEvent.Handler() {
                @Override
                public void onAttachOrDetach(AttachEvent event) {
                    activateTrigger();
                }
            });
        }
    }

    private void activateTrigger() {
        if (inHandler != null) {
            inHandler.removeHandler();
        }

        if (outHandler != null) {
            outHandler.removeHandler();
            outHandler = null;
        }

        if (detachHandler != null) {
            detachHandler.removeHandler();
        }

        if (trigger == Trigger.DEFAULT || trigger == Trigger.HOVER) {
            widget.sinkEvents(Event.ONMOUSEOVER);
            widget.sinkEvents(Event.ONMOUSEOUT);

            inHandler = widget.addHandler(new MouseOverHandler() {
                @Override
                public void onMouseOver(MouseOverEvent event) {
                    show();
                }
            }, MouseOverEvent.getType());

            outHandler = widget.addHandler(new MouseOutHandler() {
                @Override
                public void onMouseOut(MouseOutEvent event) {
                    hide();
                }
            }, MouseOutEvent.getType());
        } else if (trigger == Trigger.CLICK) {
            widget.sinkEvents(Event.ONCLICK);

            inHandler = widget.addHandler(new ClickHandler() {
                @Override
                public void onClick(ClickEvent event) {
                    toggle();
                }
            }, ClickEvent.getType());
        } else if (trigger == Trigger.FOCUS) {
            widget.sinkEvents(Event.ONFOCUS);
            widget.sinkEvents(Event.ONBLUR);

            inHandler = widget.addHandler(new FocusHandler() {
                @Override
                public void onFocus(FocusEvent event) {
                    show();
                }
            }, FocusEvent.getType());
            outHandler = widget.addHandler(new BlurHandler() {
                @Override
                public void onBlur(BlurEvent event) {
                    hide();
                }
            }, BlurEvent.getType());
        }

        detachHandler = widget.addAttachHandler(new AttachEvent.Handler() {
            @Override
            public void onAttachOrDetach(AttachEvent event) {
                if (!event.isAttached()) {
                    hide();
                }
            }
        });
    }

}